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


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

entity logic_mult is
    port (
        a       : in  std_logic_vector(7 downto 0);
        b       : in  std_logic_vector(7 downto 0);
        result  : out std_logic_vector(15 downto 0)
    );
end logic_mult;

architecture rtl of logic_mult is
begin
    -- Комбинационное умножение (оператор *)
    -- Синтезатор реализует это на логических элементах (LUT)
    result <= std_logic_vector(unsigned(a) * unsigned(b));
end rtl;


library ieee;
use ieee.std_logic_1164.all;

entity control_pulse_gen is
    port (
        clk       : in  std_logic;
        btn_ip    : in  std_logic;
        btn_logic : in  std_logic;
        slow      : out std_logic;
        use_ip    : out std_logic
    );
end control_pulse_gen;

architecture rtl of control_pulse_gen is
    signal btn_ip_d1, btn_ip_d2 : std_logic := '0';
    signal btn_logic_d1, btn_logic_d2 : std_logic := '0';
    signal slow_ip, slow_logic : std_logic;
begin

    process(clk)
    begin
        if rising_edge(clk) then
            btn_ip_d1 <= btn_ip;
            btn_ip_d2 <= btn_ip_d1;
            
            btn_logic_d1 <= btn_logic;
            btn_logic_d2 <= btn_logic_d1;
        end if;
    end process;

    slow_ip <= btn_ip_d1 and not btn_ip_d2;
    slow_logic <= btn_logic_d1 and not btn_logic_d2;

    process(clk)
    begin
        if rising_edge(clk) then
            if slow_ip = '1' and slow_logic = '1' then
                slow <= '0';
                use_ip <= '0';
            elsif slow_ip = '1' then
                slow <= '1';
                use_ip <= '1';
            elsif slow_logic = '1' then
                slow <= '1';
                use_ip <= '0';
            else
                slow <= '0';
            end if;
        end if;
    end process;

end rtl;

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

entity mult_controller is
    port (
        clk            : in  std_logic;
        reset_btn      : in  std_logic;
        slow           : in  std_logic;
        use_ip         : in  std_logic;
        result_valid   : out std_logic;
        bcd_0          : out integer range 0 to 9;
        bcd_1          : out integer range 0 to 9;
        bcd_2          : out integer range 0 to 9;
        bcd_3          : out integer range 0 to 9;
        bcd_4          : out integer range 0 to 9;
        -- Отладочные выходы
        reg_a_dbg      : out std_logic_vector(7 downto 0);
        reg_b_dbg      : out std_logic_vector(7 downto 0);
        reg_c_dbg      : out std_logic_vector(15 downto 0);
        display_reg_dbg: out std_logic_vector(15 downto 0)
    );
end mult_controller;

architecture rtl of mult_controller is

    constant NUM_A : std_logic_vector(7 downto 0) := std_logic_vector(to_unsigned(12, 8));
    constant NUM_B : std_logic_vector(7 downto 0) := std_logic_vector(to_unsigned(15, 8));

    signal mux_a_out : std_logic_vector(7 downto 0);
    signal mux_b_out : std_logic_vector(7 downto 0);

    signal reg_a : std_logic_vector(7 downto 0);
    signal reg_b : std_logic_vector(7 downto 0);

    -- Выходы обоих умножителей
    signal mult_ip_result    : std_logic_vector(15 downto 0);
    signal mult_logic_result : std_logic_vector(15 downto 0);
    signal selected_result   : std_logic_vector(15 downto 0);

    signal slow_reg : std_logic;
    signal slow_d1  : std_logic;
    
    signal reg_c : std_logic_vector(15 downto 0);
    signal res_valid_reg : std_logic;

    signal display_reg : std_logic_vector(15 downto 0);

begin

    -- 1. Мультиплексоры
    mux_a_out <= NUM_A when slow = '1' else (others => '0');
    mux_b_out <= NUM_B when slow = '1' else (others => '0');

    -- 2. Регистры после мультиплексоров (входы умножителей)
    process(clk)
    begin
        if rising_edge(clk) then
            if reset_btn = '1' then
                reg_a <= (others => '0');
                reg_b <= (others => '0');
            else
                reg_a <= mux_a_out;
                reg_b <= mux_b_out;
            end if;
        end if;
    end process;

    -- 3. IP-ядро умножителя
    u_mult_ip : entity work.mult_ip
        port map (
            dataa  => reg_a,
            datab  => reg_b,
            result => mult_ip_result
        );

    -- 4. Комбинационный умножитель (отдельный модуль)
    u_logic_mult : entity work.logic_mult
        port map (
            a      => reg_a,
            b      => reg_b,
            result => mult_logic_result
        );

    -- 5. Выбор результата (IP или логический)
    selected_result <= mult_ip_result when use_ip = '1' else mult_logic_result;

    -- 6. Регистры для slow
    process(clk)
    begin
        if rising_edge(clk) then
            slow_reg <= slow;
            slow_d1  <= slow;
        end if;
    end process;

    -- 7. Основной регистр reg_c (обнуляется)
    process(clk)
    begin
        if rising_edge(clk) then
            if reset_btn = '1' then
                reg_c <= (others => '0');
                res_valid_reg <= '0';
            elsif slow_d1 = '1' then
                reg_c <= selected_result;
                res_valid_reg <= '1';
            else
                reg_c <= (others => '0');
                res_valid_reg <= '0';
            end if;
        end if;
    end process;

    -- 8. Регистр БЕЗ СБРОСА для дисплея
    process(clk)
    begin
        if rising_edge(clk) then
            if slow_d1 = '1' then
                display_reg <= selected_result;
            end if;
        end if;
    end process;

    -- 9. BCD из display_reg
    bcd_0 <= to_integer((unsigned(display_reg) / 10000) mod 10);
    bcd_1 <= to_integer((unsigned(display_reg) / 1000)  mod 10);
    bcd_2 <= to_integer((unsigned(display_reg) / 100)   mod 10);
    bcd_3 <= to_integer((unsigned(display_reg) / 10)    mod 10);
    bcd_4 <= to_integer(unsigned(display_reg) mod 10);

    -- Выходы
    result_valid    <= res_valid_reg;
    reg_a_dbg       <= reg_a;
    reg_b_dbg       <= reg_b;
    reg_c_dbg       <= reg_c;
    display_reg_dbg <= display_reg;

end rtl;

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

entity sem_mult_top is
    port (
        clk            : in  std_logic;
        reset_btn      : in  std_logic;
        show_ip_btn    : in  std_logic;
        show_logic_btn : in  std_logic;
        ind            : out std_logic_vector(4 downto 0);
        seg            : out std_logic_vector(7 downto 0)
    );
end sem_mult_top;

architecture rtl of sem_mult_top is

    signal reset_clean      : std_logic;
    signal show_ip_clean    : std_logic;
    signal show_logic_clean : std_logic;

    signal slow             : std_logic;
    signal use_ip           : std_logic;
    signal result_valid     : std_logic;

    signal bcd_0, bcd_1, bcd_2, bcd_3, bcd_4 : integer range 0 to 9;
    signal char_0, char_1, char_2, char_3, char_4 : std_logic_vector(7 downto 0);

    -- Отладочные сигналы
    signal reg_a_dbg      : std_logic_vector(7 downto 0);
    signal reg_b_dbg      : std_logic_vector(7 downto 0);
    signal reg_c_dbg      : std_logic_vector(15 downto 0);
    signal display_reg_dbg: std_logic_vector(15 downto 0);

begin

    u_btn_reset : entity work.button_debounce
        port map (clk => clk, btn_in => reset_btn, btn_clean => reset_clean);

    u_btn_show_ip : entity work.button_debounce
        port map (clk => clk, btn_in => show_ip_btn, btn_clean => show_ip_clean);

    u_btn_show_logic : entity work.button_debounce
        port map (clk => clk, btn_in => show_logic_btn, btn_clean => show_logic_clean);

    u_pulse_gen : entity work.control_pulse_gen
        port map (
            clk       => clk,
            btn_ip    => show_ip_clean,
            btn_logic => show_logic_clean,
            slow      => slow,
            use_ip    => use_ip
        );

    u_mult_ctrl : entity work.mult_controller
        port map (
            clk             => clk,
            reset_btn       => reset_clean,
            slow            => slow,
            use_ip          => use_ip,
            result_valid    => result_valid,
            bcd_0           => bcd_0,
            bcd_1           => bcd_1,
            bcd_2           => bcd_2,
            bcd_3           => bcd_3,
            bcd_4           => bcd_4,
            reg_a_dbg       => reg_a_dbg,
            reg_b_dbg       => reg_b_dbg,
            reg_c_dbg       => reg_c_dbg,
            display_reg_dbg => display_reg_dbg
        );

    u_bcd_conv : entity work.bcd_converter
        port map (
            bcd_0  => bcd_0,
            bcd_1  => bcd_1,
            bcd_2  => bcd_2,
            bcd_3  => bcd_3,
            bcd_4  => bcd_4,
            char_0 => char_0,
            char_1 => char_1,
            char_2 => char_2,
            char_3 => char_3,
            char_4 => char_4
        );

    u_display : entity work.display_output
        port map (
            clk    => clk,
            char_0 => char_0,
            char_1 => char_1,
            char_2 => char_2,
            char_3 => char_3,
            char_4 => char_4,
            ind    => ind,
            seg    => seg
        );

end rtl;