Загрузка данных
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