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


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 : std_logic_vector(7 downto 0);
    signal mux_b : std_logic_vector(7 downto 0);
    signal mult_result : std_logic_vector(15 downto 0);
    signal result_reg : unsigned(15 downto 0) := (others => '0');
    signal enable_reg : std_logic := '0';
    signal bcd_reg_0 : integer range 0 to 9 := 0;
    signal bcd_reg_1 : integer range 0 to 9 := 0;
    signal bcd_reg_2 : integer range 0 to 9 := 0;
    signal bcd_reg_3 : integer range 0 to 9 := 0;
    signal bcd_reg_4 : integer range 0 to 9 := 0;

begin

    -- ✅ ИНВЕРТИРОВАННАЯ логика MUX:
    -- Когда slow='0' → операнды (вход 0)
    -- Когда slow='1' → нули (вход 1)
    mux_a <= (others => '0') when slow = '1' else std_logic_vector(NUM_A);
    mux_b <= (others => '0') when slow = '1' else std_logic_vector(NUM_B);

    u_mult_ip : entity work.mult_ip
        port map (dataa => mux_a, datab => mux_b, result => mult_result);

    process(clk)
    begin
        if rising_edge(clk) then
            if slow_fall = '1' then
                result_reg <= unsigned(mult_result);
                enable_reg <= '1';
            end if;
        end if;
    end process;

    process(clk)
    begin
        if rising_edge(clk) then
            if enable_reg = '1' then
                bcd_reg_0 <= to_integer((result_reg / 10000) mod 10);
                bcd_reg_1 <= to_integer((result_reg / 1000) mod 10);
                bcd_reg_2 <= to_integer((result_reg / 100) mod 10);
                bcd_reg_3 <= to_integer((result_reg / 10) mod 10);
                bcd_reg_4 <= to_integer(result_reg mod 10);
            end if;
        end if;
    end process;

    result_valid <= enable_reg;
    bcd_0 <= bcd_reg_0; bcd_1 <= bcd_reg_1; bcd_2 <= bcd_reg_2;
    bcd_3 <= bcd_reg_3; bcd_4 <= bcd_reg_4;

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 : unsigned(7 downto 0);
    signal mux_b : unsigned(7 downto 0);
    signal mult_result : unsigned(15 downto 0);
    signal result_reg : unsigned(15 downto 0) := (others => '0');
    signal enable_reg : std_logic := '0';
    signal bcd_reg_0 : integer range 0 to 9 := 0;
    signal bcd_reg_1 : integer range 0 to 9 := 0;
    signal bcd_reg_2 : integer range 0 to 9 := 0;
    signal bcd_reg_3 : integer range 0 to 9 := 0;
    signal bcd_reg_4 : integer range 0 to 9 := 0;

begin

    -- ✅ ИНВЕРТИРОВАННАЯ логика MUX:
    mux_a <= (others => '0') when slow = '1' else NUM_A;
    mux_b <= (others => '0') when slow = '1' else NUM_B;

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

    process(clk)
    begin
        if rising_edge(clk) then
            if slow_fall = '1' then
                result_reg <= mult_result;
                enable_reg <= '1';
            end if;
        end if;
    end process;

    process(clk)
    begin
        if rising_edge(clk) then
            if enable_reg = '1' then
                bcd_reg_0 <= to_integer((result_reg / 10000) mod 10);
                bcd_reg_1 <= to_integer((result_reg / 1000) mod 10);
                bcd_reg_2 <= to_integer((result_reg / 100) mod 10);
                bcd_reg_3 <= to_integer((result_reg / 10) mod 10);
                bcd_reg_4 <= to_integer(result_reg mod 10);
            end if;
        end if;
    end process;

    result_valid <= enable_reg;
    bcd_0 <= bcd_reg_0; bcd_1 <= bcd_reg_1; bcd_2 <= bcd_reg_2;
    bcd_3 <= bcd_reg_3; bcd_4 <= bcd_reg_4;

end rtl;

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;
        slow       : out std_logic;
        slow_fall  : out std_logic
    );
end slow_generator;

architecture rtl of slow_generator is

    signal show_prev       : std_logic := '0';
    signal slow_internal   : std_logic := '0';
    signal slow_prev       : std_logic := '0';

begin

    -- Детектор фронта кнопки → Slow (1 такт)
    process(clk)
    begin
        if rising_edge(clk) then
            if reset_btn = '1' then
                show_prev <= '0';
                slow_internal <= '0';
            else
                show_prev <= show_btn;
                -- Slow = 1 на 1 такт при нажатии кнопки (переход 1→0)
                if show_btn = '0' and show_prev = '1' then
                    slow_internal <= '1';
                else
                    slow_internal <= '0';
                end if;
            end if;
        end if;
    end process;

    -- Детектор спада Slow
    process(clk)
    begin
        if rising_edge(clk) then
            if reset_btn = '1' then
                slow_prev <= '0';
            else
                slow_prev <= slow_internal;
            end if;
        end if;
    end process;
    
    slow_fall <= slow_prev and not slow_internal;
    slow <= slow_internal;

end rtl;