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


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 reg_a : unsigned(7 downto 0) := (others => '0');
    signal reg_b : unsigned(7 downto 0) := (others => '0');

    -- Выходы мультиплексоров
    signal mux_a : unsigned(7 downto 0);
    signal 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

    -- Регистры операндов
    process(clk)
    begin
        if rising_edge(clk) then
            reg_a <= NUM_A;
            reg_b <= NUM_B;
        end if;
    end process;

    -- MUX1: slow='1' → reg_a, иначе 0
    mux_a <= reg_a when slow = '1' else (others => '0');
    
    -- MUX2: slow='1' → reg_b, иначе 0
    mux_b <= reg_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;

    -- Выходной регистр
    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 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 reg_a : unsigned(7 downto 0) := (others => '0');
    signal reg_b : unsigned(7 downto 0) := (others => '0');

    -- Выходы мультиплексоров
    signal mux_a : std_logic_vector(7 downto 0);
    signal mux_b : std_logic_vector(7 downto 0);

    -- IP умножитель
    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

    -- Регистры операндов (хранят значения постоянно)
    process(clk)
    begin
        if rising_edge(clk) then
            reg_a <= NUM_A;
            reg_b <= NUM_B;
        end if;
    end process;

    -- MUX1: slow='1' → пропускает reg_a, иначе 0
    mux_a <= std_logic_vector(reg_a) when slow = '1' else (others => '0');
    
    -- MUX2: slow='1' → пропускает reg_b, иначе 0
    mux_b <= std_logic_vector(reg_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);

    -- Выходной регистр (захват по спаду 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;