Загрузка данных
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity calculator is
port (
clk : in std_logic;
reset : in std_logic;
key : in std_logic_vector(1 downto 0);
result : out integer;
s_a : out std_logic_vector(7 downto 0); -- Для Signal Tap
s_b : out std_logic_vector(7 downto 0); -- Для Signal Tap
s_result : out integer -- Для Signal Tap
);
end calculator;
architecture rtl of calculator is
-- Константы
constant A_VAL : integer := 5; -- Множитель A (можно менять)
constant B_VAL : integer := 7; -- Множитель B (можно менять)
-- Компоненты
component mult_5 is
port (
dataa : in std_logic_vector(7 downto 0);
datab : in std_logic_vector(7 downto 0);
result : out std_logic_vector(15 downto 0)
);
end component;
component logic is
port (
a : in integer;
b : in integer;
result : out integer
);
end component;
-- Сигналы мультиплексоров и регистров
signal mux_a : std_logic_vector(7 downto 0);
signal mux_b : std_logic_vector(7 downto 0);
signal reg_a : std_logic_vector(7 downto 0) := (others => '0');
signal reg_b : std_logic_vector(7 downto 0) := (others => '0');
-- Сигналы результатов
signal dsp_result_vec : std_logic_vector(15 downto 0);
signal dsp_result_int : integer;
signal logic_result : integer;
-- Сигналы управления
signal capture_en : std_logic := '0';
signal mode : std_logic := '0'; -- '0' = logic, '1' = DSP
-- Счётчик для управления захватом
signal counter : integer range 0 to 50000000 := 0;
constant DIVIDER : integer := 50000000; -- 1 секунда при 50 МГц
-- Состояния конечного автомата
type state_type is (IDLE, CAPTURE, MULTIPLY, HOLD);
signal state : state_type := IDLE;
begin
-- ========================================
-- МУЛЬТИПЛЕКСОРЫ (выбор A/0 или B/0)
-- ========================================
mux_a <= std_logic_vector(to_unsigned(A_VAL, 8)) when capture_en = '1' else (others => '0');
mux_b <= std_logic_vector(to_unsigned(B_VAL, 8)) when capture_en = '1' else (others => '0');
-- ========================================
-- РЕГИСТРЫ (захват значений)
-- ========================================
process(clk, reset)
begin
if reset = '1' then
reg_a <= (others => '0');
reg_b <= (others => '0');
elsif rising_edge(clk) then
if capture_en = '1' then
reg_a <= mux_a;
reg_b <= mux_b;
else
reg_a <= (others => '0');
reg_b <= (others => '0');
end if;
end if;
end process;
-- ========================================
-- КОНЕЧНЫЙ АВТОМАТ УПРАВЛЕНИЯ
-- ========================================
process(clk, reset)
begin
if reset = '1' then
state <= IDLE;
counter <= 0;
capture_en <= '0';
elsif rising_edge(clk) then
case state is
when IDLE =>
capture_en <= '0';
if counter >= DIVIDER - 1 then
counter <= 0;
state <= CAPTURE;
else
counter <= counter + 1;
end if;
when CAPTURE =>
capture_en <= '1';
state <= MULTIPLY;
when MULTIPLY =>
capture_en <= '0';
state <= HOLD;
when HOLD =>
capture_en <= '0';
if counter >= DIVIDER - 1 then
counter <= 0;
state <= CAPTURE;
else
counter <= counter + 1;
end if;
end case;
end if;
end process;
-- ========================================
-- УМНОЖИТЕЛИ
-- ========================================
-- DSP умножитель (mult_5)
mult_inst: mult_5
port map (
dataa => reg_a,
datab => reg_b,
result => dsp_result_vec
);
dsp_result_int <= to_integer(unsigned(dsp_result_vec));
-- Логический умножитель (logic)
logic_inst: logic
port map (
a => to_integer(unsigned(reg_a)),
b => to_integer(unsigned(reg_b)),
result => logic_result
);
-- ========================================
-- ВЫБОР РЕЖИМА ПО КНОПКЕ
-- ========================================
process(clk, reset)
begin
if reset = '1' then
mode <= '0';
elsif rising_edge(clk) then
if key(1) = '0' then -- Кнопка 1 переключает режим
mode <= not mode;
end if;
end if;
end process;
-- ========================================
-- ВЫХОДНЫЕ СИГНАЛЫ
-- ========================================
s_a <= reg_a; -- Для просмотра в Signal Tap
s_b <= reg_b; -- Для просмотра в Signal Tap
result <= logic_result when mode = '0' else dsp_result_int;
s_result <= logic_result when mode = '0' else dsp_result_int;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity calculator_top is
port (
clk : in std_logic;
reset : in std_logic;
key : in std_logic_vector(1 downto 0);
led : out std_logic_vector(7 downto 0) -- Простой вывод для теста
);
end calculator_top;
architecture struct of calculator_top is
component calculator is
port (
clk : in std_logic;
reset : in std_logic;
key : in std_logic_vector(1 downto 0);
result : out integer;
s_a : out std_logic_vector(7 downto 0);
s_b : out std_logic_vector(7 downto 0);
s_result : out integer
);
end component;
signal result_int : integer;
signal s_a, s_b : std_logic_vector(7 downto 0);
signal s_result : integer;
begin
calc_inst: calculator
port map (
clk => clk,
reset => reset,
key => key,
result => result_int,
s_a => s_a,
s_b => s_b,
s_result => s_result
);
-- Вывод младшего байта результата на светодиоды
led <= std_logic_vector(to_unsigned(result_int mod 256, 8));
end struct;