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


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

entity slow_generator is
    port (
        clk        : in  std_logic;
        reset_btn  : in  std_logic;
        show_btn   : in  std_logic;  -- Активный низкий уровень (кнопка нажата = '0')
        slow       : out std_logic;
        slow_fall  : out std_logic
    );
end slow_generator;

architecture rtl of slow_generator is
    signal btn_sync1 : std_logic := '0';
    signal btn_sync2 : std_logic := '0';
    signal btn_prev  : std_logic := '0';
    signal slow_int  : std_logic := '0';
    signal slow_prev : std_logic := '0';
begin

    process(clk)
    begin
        if rising_edge(clk) then
            if reset_btn = '1' then
                btn_sync1 <= '0'; btn_sync2 <= '0';
                btn_prev  <= '0'; slow_int <= '0';
            else
                -- Синхронизация кнопки
                btn_sync1 <= show_btn;
                btn_sync2 <= btn_sync1;
                btn_prev  <= btn_sync2;
                
                -- Детектор нажатия (переход 1->0)
                if btn_sync2 = '0' and btn_prev = '1' then
                    slow_int <= '1';  -- Slow = 1 на 1 такт
                else
                    slow_int <= '0';
                end if;
            end if;
        end if;
    end process;

    -- Детектор спада slow для захвата результата
    process(clk)
    begin
        if rising_edge(clk) then
            slow_prev <= slow_int;
        end if;
    end process;
    
    slow_fall <= slow_prev and not slow_int;
    slow      <= slow_int;

end rtl;


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

entity ip_multiplier is
    port (
        clk          : in  std_logic;
        slow         : in  std_logic;
        slow_fall    : 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 ip_multiplier;

architecture rtl of ip_multiplier 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, mux_b : std_logic_vector(7 downto 0);
    signal mult_out     : std_logic_vector(15 downto 0);
    signal result_reg   : unsigned(15 downto 0) := (others => '0');
    signal enable_reg   : std_logic := '0';

begin

    -- MUX1: Вход 1 = A, Вход 0 = 0. Управляется slow
    mux_a <= std_logic_vector(NUM_A) when slow = '1' else (others => '0');
    
    -- MUX2: Вход 1 = B, Вход 0 = 0. Управляется slow
    mux_b <= std_logic_vector(NUM_B) when slow = '1' else (others => '0');

    -- IP-ядро умножителя
    u_ip_mult : entity work.mult_ip
        port map (dataa => mux_a, datab => mux_b, result => mult_out);

    -- D-триггер: захват результата по спаду slow_fall
    process(clk)
    begin
        if rising_edge(clk) then
            if slow_fall = '1' then
                result_reg <= unsigned(mult_out);
                enable_reg <= '1';
            end if;
        end if;
    end process;

    -- BCD преобразование (внутри модуля умножения)
    process(clk)
    begin
        if rising_edge(clk) then
            if enable_reg = '1' then
                bcd_0 <= to_integer((result_reg / 10000) mod 10);
                bcd_1 <= to_integer((result_reg / 1000) mod 10);
                bcd_2 <= to_integer((result_reg / 100) mod 10);
                bcd_3 <= to_integer((result_reg / 10) mod 10);
                bcd_4 <= to_integer(result_reg mod 10);
            end if;
        end if;
    end process;

    result_valid <= enable_reg;

end rtl;


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

entity logic_multiplier is
    port (
        clk          : in  std_logic;
        slow         : in  std_logic;
        slow_fall    : 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 logic_multiplier;

architecture rtl of logic_multiplier 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, mux_b : unsigned(7 downto 0);
    signal mult_out     : unsigned(15 downto 0);
    signal result_reg   : unsigned(15 downto 0) := (others => '0');
    signal enable_reg   : std_logic := '0';

begin

    -- MUX1: Вход 1 = A, Вход 0 = 0
    mux_a <= NUM_A when slow = '1' else (others => '0');
    
    -- MUX2: Вход 1 = B, Вход 0 = 0
    mux_b <= NUM_B when slow = '1' else (others => '0');

    -- Логический умножитель (Shift-and-Add)
    process(mux_a, mux_b)
        variable temp : unsigned(15 downto 0);
    begin
        temp := (others => '0');
        for i in 0 to 7 loop
            if mux_b(i) = '1' then
                temp := temp + (mux_a sll i);
            end if;
        end loop;
        mult_out <= temp;
    end process;

    -- D-триггер: захват по спаду slow_fall
    process(clk)
    begin
        if rising_edge(clk) then
            if slow_fall = '1' then
                result_reg <= mult_out;
                enable_reg <= '1';
            end if;
        end if;
    end process;

    -- BCD преобразование
    process(clk)
    begin
        if rising_edge(clk) then
            if enable_reg = '1' then
                bcd_0 <= to_integer((result_reg / 10000) mod 10);
                bcd_1 <= to_integer((result_reg / 1000) mod 10);
                bcd_2 <= to_integer((result_reg / 100) mod 10);
                bcd_3 <= to_integer((result_reg / 10) mod 10);
                bcd_4 <= to_integer(result_reg mod 10);
            end if;
        end if;
    end process;

    result_valid <= enable_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 slow_ip, slow_ip_fall   : std_logic;
    signal slow_log, slow_log_fall : std_logic;
    
    signal ip_valid, log_valid     : std_logic;
    signal ip_bcd(4 downto 0)      : integer range 0 to 9;
    signal log_bcd(4 downto 0)     : integer range 0 to 9;
    signal final_bcd(4 downto 0)   : integer range 0 to 9;
    signal final_valid             : std_logic;
    
    signal char_0, char_1, char_2, char_3, char_4 : std_logic_vector(7 downto 0);

begin

    -- Генераторы slow
    u_slow_ip : entity work.slow_generator
        port map (clk => clk, reset_btn => reset_btn, show_btn => show_ip_btn,
                  slow => slow_ip, slow_fall => slow_ip_fall);
                  
    u_slow_log : entity work.slow_generator
        port map (clk => clk, reset_btn => reset_btn, show_btn => show_logic_btn,
                  slow => slow_log, slow_fall => slow_log_fall);

    -- Модули умножения
    u_ip_mult : entity work.ip_multiplier
        port map (clk => clk, slow => slow_ip, slow_fall => slow_ip_fall,
                  result_valid => ip_valid, bcd_0 => ip_bcd(0), bcd_1 => ip_bcd(1),
                  bcd_2 => ip_bcd(2), bcd_3 => ip_bcd(3), bcd_4 => ip_bcd(4));

    u_log_mult : entity work.logic_multiplier
        port map (clk => clk, slow => slow_log, slow_fall => slow_log_fall,
                  result_valid => log_valid, bcd_0 => log_bcd(0), bcd_1 => log_bcd(1),
                  bcd_2 => log_bcd(2), bcd_3 => log_bcd(3), bcd_4 => log_bcd(4));

    -- Выбор активного результата
    final_valid <= ip_valid or log_valid;
    gen_final: for i in 0 to 4 generate
        final_bcd(i) <= ip_bcd(i) when ip_valid = '1' else log_bcd(i);
    end generate;

    -- BCD -> Сегменты (используйте ваш существующий bcd_converter.vhd)
    u_bcd : entity work.bcd_converter
        port map (result_valid => final_valid, bcd_0 => final_bcd(0), bcd_1 => final_bcd(1),
                  bcd_2 => final_bcd(2), bcd_3 => final_bcd(3), bcd_4 => final_bcd(4),
                  char_0 => char_0, char_1 => char_1, char_2 => char_2, char_3 => char_3, char_4 => char_4);

    -- Дисплей (используйте ваш существующий display_output.vhd)
    u_disp : 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