Загрузка данных
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 ip_valid : std_logic;
signal logic_valid : std_logic;
signal ip_bcd_0 : integer range 0 to 9;
signal ip_bcd_1 : integer range 0 to 9;
signal ip_bcd_2 : integer range 0 to 9;
signal ip_bcd_3 : integer range 0 to 9;
signal ip_bcd_4 : integer range 0 to 9;
signal logic_bcd_0 : integer range 0 to 9;
signal logic_bcd_1 : integer range 0 to 9;
signal logic_bcd_2 : integer range 0 to 9;
signal logic_bcd_3 : integer range 0 to 9;
signal logic_bcd_4 : integer range 0 to 9;
signal final_valid : std_logic;
signal final_bcd_0 : integer range 0 to 9;
signal final_bcd_1 : integer range 0 to 9;
signal final_bcd_2 : integer range 0 to 9;
signal final_bcd_3 : integer range 0 to 9;
signal final_bcd_4 : integer range 0 to 9;
signal char_0 : std_logic_vector(7 downto 0);
signal char_1 : std_logic_vector(7 downto 0);
signal char_2 : std_logic_vector(7 downto 0);
signal char_3 : std_logic_vector(7 downto 0);
signal char_4 : std_logic_vector(7 downto 0);
begin
-- Модуль 1: IP умножитель (НЕЗАВИСИМАЯ СХЕМА)
u_ip_mult : entity work.ip_multiplier
port map (
clk => clk,
reset_btn => reset_btn,
show_btn => show_ip_btn,
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
);
-- Модуль 2: Логический умножитель (НЕЗАВИСИМАЯ СХЕМА)
u_logic_mult : entity work.logic_multiplier
port map (
clk => clk,
reset_btn => reset_btn,
show_btn => show_logic_btn,
result_valid => logic_valid,
bcd_0 => logic_bcd_0,
bcd_1 => logic_bcd_1,
bcd_2 => logic_bcd_2,
bcd_3 => logic_bcd_3,
bcd_4 => logic_bcd_4
);
-- Выбор результата (какой модуль активен)
final_valid <= ip_valid or logic_valid;
process(ip_valid, logic_valid, ip_bcd_0, ip_bcd_1, ip_bcd_2, ip_bcd_3, ip_bcd_4,
logic_bcd_0, logic_bcd_1, logic_bcd_2, logic_bcd_3, logic_bcd_4)
begin
if ip_valid = '1' then
final_bcd_0 <= ip_bcd_0;
final_bcd_1 <= ip_bcd_1;
final_bcd_2 <= ip_bcd_2;
final_bcd_3 <= ip_bcd_3;
final_bcd_4 <= ip_bcd_4;
else
final_bcd_0 <= logic_bcd_0;
final_bcd_1 <= logic_bcd_1;
final_bcd_2 <= logic_bcd_2;
final_bcd_3 <= logic_bcd_3;
final_bcd_4 <= logic_bcd_4;
end if;
end process;
-- BCD конвертер
u_bcd_conv : 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
);
-- Дисплей
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;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ip_multiplier is
port (
clk : in std_logic;
reset_btn : in std_logic;
show_btn : 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 show_clean : std_logic;
-- Детектор фронта кнопки
signal show_prev : std_logic := '0';
-- Сигнал Slow (1 такт после нажатия)
signal slow : std_logic := '0';
-- Детектор спада Slow
signal slow_prev : std_logic := '0';
signal slow_fall : std_logic;
-- Мультиплексоры
signal mux_a : std_logic_vector(7 downto 0);
signal mux_b : std_logic_vector(7 downto 0);
-- IP-ядро умножителя
signal mult_result : std_logic_vector(15 downto 0);
-- D-триггер (регистр C)
signal result_reg : unsigned(15 downto 0) := (others => '0');
signal enable_reg : std_logic := '0';
-- BCD цифры
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
-- ==========================================
-- 1. Фильтр кнопки
-- ==========================================
process(clk)
variable counter : integer range 0 to 1000000 := 0;
begin
if rising_edge(clk) then
if reset_btn = '0' then
if counter < 1000000 then
counter := counter + 1;
else
show_clean <= '1';
end if;
else
counter := 0;
show_clean <= '0';
end if;
end if;
end process;
-- ==========================================
-- 2. Детектор фронта кнопки → Slow (1 такт)
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
show_prev <= '0';
slow <= '0';
else
show_prev <= show_clean;
if show_clean = '1' and show_prev = '0' then
slow <= '1';
else
slow <= '0';
end if;
end if;
end if;
end process;
-- ==========================================
-- 3. Детектор спада Slow
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
slow_prev <= '0';
else
slow_prev <= slow;
end if;
end if;
end process;
slow_fall <= slow_prev and not slow;
-- ==========================================
-- 4. Мультиплексоры (A и B)
-- ==========================================
-- MUX A: если Slow=1 → A, иначе → 0
mux_a <= std_logic_vector(NUM_A) when slow = '1' else (others => '0');
-- MUX B: если Slow=1 → B, иначе → 0
mux_b <= std_logic_vector(NUM_B) when slow = '1' else (others => '0');
-- ==========================================
-- 5. IP-ядро умножителя
-- ==========================================
u_mult_ip : entity work.mult_ip
port map (
dataa => mux_a,
datab => mux_b,
result => mult_result
);
-- ==========================================
-- 6. D-триггер (захват по спаду Slow)
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
result_reg <= (others => '0');
enable_reg <= '0';
elsif slow_fall = '1' then
-- По спаду Slow сохраняем результат
result_reg <= unsigned(mult_result);
enable_reg <= '1';
end if;
end if;
end process;
-- ==========================================
-- 7. Преобразование в BCD
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
bcd_reg_0 <= 0; bcd_reg_1 <= 0; bcd_reg_2 <= 0;
bcd_reg_3 <= 0; bcd_reg_4 <= 0;
elsif 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;
reset_btn : in std_logic;
show_btn : 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 show_clean : std_logic;
-- Детектор фронта кнопки
signal show_prev : std_logic := '0';
-- Сигнал Slow (1 такт после нажатия)
signal slow : std_logic := '0';
-- Детектор спада Slow
signal slow_prev : std_logic := '0';
signal slow_fall : std_logic;
-- Мультиплексоры
signal mux_a : unsigned(7 downto 0);
signal mux_b : unsigned(7 downto 0);
-- Логический умножитель (Shift-and-Add)
signal mult_result : unsigned(15 downto 0);
-- D-триггер (регистр C)
signal result_reg : unsigned(15 downto 0) := (others => '0');
signal enable_reg : std_logic := '0';
-- BCD цифры
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
-- ==========================================
-- 1. Фильтр кнопки
-- ==========================================
process(clk)
variable counter : integer range 0 to 1000000 := 0;
begin
if rising_edge(clk) then
if reset_btn = '0' then
if counter < 1000000 then
counter := counter + 1;
else
show_clean <= '1';
end if;
else
counter := 0;
show_clean <= '0';
end if;
end if;
end process;
-- ==========================================
-- 2. Детектор фронта кнопки → Slow (1 такт)
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
show_prev <= '0';
slow <= '0';
else
show_prev <= show_clean;
if show_clean = '1' and show_prev = '0' then
slow <= '1';
else
slow <= '0';
end if;
end if;
end if;
end process;
-- ==========================================
-- 3. Детектор спада Slow
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
slow_prev <= '0';
else
slow_prev <= slow;
end if;
end if;
end process;
slow_fall <= slow_prev and not slow;
-- ==========================================
-- 4. Мультиплексоры (A и B)
-- ==========================================
mux_a <= NUM_A when slow = '1' else (others => '0');
mux_b <= NUM_B when slow = '1' else (others => '0');
-- ==========================================
-- 5. Логический умножитель (Shift-and-Add)
-- ==========================================
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;
-- ==========================================
-- 6. D-триггер (захват по спаду Slow)
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
result_reg <= (others => '0');
enable_reg <= '0';
elsif slow_fall = '1' then
result_reg <= mult_result;
enable_reg <= '1';
end if;
end if;
end process;
-- ==========================================
-- 7. Преобразование в BCD
-- ==========================================
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
bcd_reg_0 <= 0; bcd_reg_1 <= 0; bcd_reg_2 <= 0;
bcd_reg_3 <= 0; bcd_reg_4 <= 0;
elsif 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;