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


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   -- импульс 1 такт
    );
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';  -- Игнорируем одновременное нажатие
            elsif slow_ip = '1' or slow_logic = '1' then
                slow <= '1';
            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;
        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
    );
end mult_controller;

architecture rtl of mult_controller is

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

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

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

    signal mult_ip_result : std_logic_vector(15 downto 0);

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

    signal display_reg : unsigned(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  => std_logic_vector(reg_a),
            datab  => std_logic_vector(reg_b),
            result => mult_ip_result
        );

    -- 4. Регистры для сигнала slow (для SignalTap и задержки)
    process(clk)
    begin
        if rising_edge(clk) then
            slow_reg <= slow;
            slow_d1  <= slow;
        end if;
    end process;

    -- 5. Основной выходной регистр (reg_c) и result_valid (Вариант B: обнуляется)
    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 <= unsigned(mult_ip_result);
                res_valid_reg <= '1';
            else
                reg_c <= (others => '0');
                res_valid_reg <= '0';
            end if;
        end if;
    end process;

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

    -- 7. Преобразование display_reg в BCD (комбинационно)
    bcd_0 <= to_integer((display_reg / 10000) mod 10);
    bcd_1 <= to_integer((display_reg / 1000)  mod 10);
    bcd_2 <= to_integer((display_reg / 100)   mod 10);
    bcd_3 <= to_integer((display_reg / 10)    mod 10);
    bcd_4 <= to_integer(display_reg mod 10);

    -- Выходы модуля
    result_valid <= res_valid_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 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);

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
        );

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

    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;