Загрузка данных
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_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 show_clean : std_logic;
signal reset_clean : std_logic;
-- Сигналы от mult_controller
signal result_valid : std_logic;
signal bcd_0 : integer range 0 to 9;
signal bcd_1 : integer range 0 to 9;
signal bcd_2 : integer range 0 to 9;
signal bcd_3 : integer range 0 to 9;
signal 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: Фильтр кнопки SHOW
u_btn_show : entity work.button_debounce
port map (
clk => clk,
btn_in => show_btn,
btn_clean => show_clean
);
-- Блок 2: Фильтр кнопки RESET
u_btn_reset : entity work.button_debounce
port map (
clk => clk,
btn_in => reset_btn,
btn_clean => reset_clean
);
-- Блок 3: Контроллер умножения (IP-ядро + регистр)
u_mult_ctrl : entity work.mult_controller
port map (
clk => clk,
show_btn => show_clean,
reset_btn => reset_clean,
result_valid=> result_valid,
bcd_0 => bcd_0,
bcd_1 => bcd_1,
bcd_2 => bcd_2,
bcd_3 => bcd_3,
bcd_4 => bcd_4
);
-- Блок 4: Преобразование BCD в коды сегментов
u_bcd_conv : entity work.bcd_converter
port map (
result_valid => result_valid,
bcd_0 => bcd_0,
bcd_1 => bcd_1,
bcd_2 => bcd_2,
bcd_3 => bcd_3,
bcd_4 => bcd_4,
char_0 => char_0,
char_1 => char_1,
char_2 => char_2,
char_3 => char_3,
char_4 => char_4
);
-- Блок 5: Вывод на дисплей (мультиплексирование)
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 button_debounce is
port (
clk : in std_logic;
btn_in : in std_logic;
btn_clean : out std_logic
);
end button_debounce;
architecture rtl of button_debounce is
signal counter : integer range 0 to 1000000 := 0;
signal btn_stable : std_logic := '0';
begin
process(clk)
begin
if rising_edge(clk) then
if btn_in = '0' then
if counter < 1000000 then
counter <= counter + 1;
else
btn_stable <= '1';
end if;
else
counter <= 0;
btn_stable <= '0';
end if;
end if;
end process;
btn_clean <= btn_stable;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity button_debounce is
port (
clk : in std_logic;
btn_in : in std_logic;
btn_clean : out std_logic
);
end button_debounce;
architecture rtl of button_debounce is
signal counter : integer range 0 to 1000000 := 0;
signal btn_stable : std_logic := '0';
begin
process(clk)
begin
if rising_edge(clk) then
if btn_in = '0' then
if counter < 1000000 then
counter <= counter + 1;
else
btn_stable <= '1';
end if;
else
counter <= 0;
btn_stable <= '0';
end if;
end if;
end process;
btn_clean <= btn_stable;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mult_controller is
port (
clk : in std_logic;
show_btn : in std_logic;
reset_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 mult_controller;
architecture rtl of mult_controller is
-- Константы: множимые числа (задаются в коде)
constant NUM_A : unsigned(7 downto 0) := to_unsigned(12, 8);
constant NUM_B : unsigned(7 downto 0) := to_unsigned(15, 8);
-- Сигналы IP-ядра
signal mult_result : unsigned(15 downto 0);
-- Регистр результата
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
-- IP-ядро умножителя
u_mult_ip : entity work.mult_ip
port map (
dataa => std_logic_vector(NUM_A),
datab => std_logic_vector(NUM_B),
result => std_logic_vector(mult_result)
);
-- Регистр результата (фиксация по кнопке)
process(clk)
begin
if rising_edge(clk) then
if reset_btn = '1' then
result_reg <= (others => '0');
enable_reg <= '0';
elsif show_btn = '1' then
result_reg <= mult_result;
enable_reg <= '1';
end if;
end if;
end process;
-- Преобразование в BCD (5 цифр для числа до 65535)
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 show_btn = '1' then
bcd_reg_0 <= to_integer((mult_result / 10000) mod 10);
bcd_reg_1 <= to_integer((mult_result / 1000) mod 10);
bcd_reg_2 <= to_integer((mult_result / 100) mod 10);
bcd_reg_3 <= to_integer((mult_result / 10) mod 10);
bcd_reg_4 <= to_integer(mult_result 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 bcd_converter is
port (
result_valid : in std_logic;
bcd_0 : in integer range 0 to 9;
bcd_1 : in integer range 0 to 9;
bcd_2 : in integer range 0 to 9;
bcd_3 : in integer range 0 to 9;
bcd_4 : in integer range 0 to 9;
char_0 : out std_logic_vector(7 downto 0);
char_1 : out std_logic_vector(7 downto 0);
char_2 : out std_logic_vector(7 downto 0);
char_3 : out std_logic_vector(7 downto 0);
char_4 : out std_logic_vector(7 downto 0)
);
end bcd_converter;
architecture rtl of bcd_converter is
type hex_array is array (0 to 9) of std_logic_vector(7 downto 0);
constant hex_codes : hex_array := (
"10000001", -- 0
"11110011", -- 1
"01001001", -- 2
"01100001", -- 3
"00110011", -- 4
"00100101", -- 5
"00000101", -- 6
"11110001", -- 7
"00000001", -- 8
"00100001" -- 9
);
begin
process(result_valid, bcd_0, bcd_1, bcd_2, bcd_3, bcd_4)
begin
if result_valid = '0' then
-- Нет результата: все пусто
char_0 <= "11111111";
char_1 <= "11111111";
char_2 <= "11111111";
char_3 <= "11111111";
char_4 <= "11111111";
else
-- Преобразуем BCD в коды сегментов
char_0 <= hex_codes(bcd_0);
char_1 <= hex_codes(bcd_1);
char_2 <= hex_codes(bcd_2);
char_3 <= hex_codes(bcd_3);
char_4 <= hex_codes(bcd_4);
end if;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity display_output is
port (
clk : in std_logic;
char_0 : in std_logic_vector(7 downto 0);
char_1 : in std_logic_vector(7 downto 0);
char_2 : in std_logic_vector(7 downto 0);
char_3 : in std_logic_vector(7 downto 0);
char_4 : in std_logic_vector(7 downto 0);
ind : out std_logic_vector(4 downto 0);
seg : out std_logic_vector(7 downto 0)
);
end display_output;
architecture rtl of display_output is
signal sel_dig : integer range 0 to 4 := 0;
signal mux_counter : integer range 0 to 100000 := 0;
begin
-- Счётчик разрядов (мультиплексирование ~500 Гц)
process(clk)
begin
if rising_edge(clk) then
if mux_counter = 100000 - 1 then
mux_counter <= 0;
if sel_dig = 4 then
sel_dig <= 0;
else
sel_dig <= sel_dig + 1;
end if;
else
mux_counter <= mux_counter + 1;
end if;
end if;
end process;
-- Вывод на дисплей
process(sel_dig, char_0, char_1, char_2, char_3, char_4)
begin
case sel_dig is
when 0 =>
ind <= "11110";
seg <= char_0;
when 1 =>
ind <= "11101";
seg <= char_1;
when 2 =>
ind <= "11011";
seg <= char_2;
when 3 =>
ind <= "10111";
seg <= char_3;
when 4 =>
ind <= "01111";
seg <= char_4;
when others =>
ind <= "11111";
seg <= "11111111";
end case;
end process;
end rtl;