Загрузка данных
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity calculator is
port(
clk : in std_logic;
key : in std_logic_vector(1 downto 0);
result : out integer;
trigger : out std_logic
);
end calculator;
architecture rtl of calculator is
-- Константы для умножения
constant A_VAL : integer := 4;
constant B_VAL : integer := 2;
-- =============================================
-- КОМПОНЕНТЫ
-- =============================================
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 key_reg : std_logic_vector(1 downto 0) := (others => '1');
signal key_prev : std_logic_vector(1 downto 0) := (others => '1');
signal mode : std_logic := '0'; -- 0=logic, 1=dsp
-- Сигнал управления мультиплексорами
signal sel : std_logic := '0';
-- ============================================================
-- ВХОДНЫЕ МУЛЬТИПЛЕКСОРЫ (выбор 0 или числа)
-- ============================================================
signal mux_a_out : std_logic_vector(7 downto 0);
signal mux_b_out : std_logic_vector(7 downto 0);
-- ============================================================
-- ТРИГГЕРЫ ДЛЯ A И B (фиксация на 1 такт)
-- ПОДКЛЮЧАЮТСЯ К ОБОИМ УМНОЖИТЕЛЯМ!
-- ============================================================
signal a_reg : std_logic_vector(7 downto 0) := (others => '0');
signal b_reg : std_logic_vector(7 downto 0) := (others => '0');
-- Сигналы для преобразования в integer
signal a_int : integer := 0;
signal b_int : integer := 0;
-- ============================================================
-- РЕЗУЛЬТАТЫ УМНОЖЕНИЙ
-- ============================================================
signal dsp_result_vec : std_logic_vector(15 downto 0);
signal dsp_result_int : integer := 0;
signal logic_result : integer := 0;
-- Регистр результата
signal result_reg : integer := 0;
signal trigger_reg : std_logic := '0';
begin
-- =============================================
-- 1. ПРЕОБРАЗОВАНИЕ ДЛЯ ЛОГИЧЕСКОГО УМНОЖЕНИЯ
-- =============================================
a_int <= to_integer(unsigned(a_reg));
b_int <= to_integer(unsigned(b_reg));
-- =============================================
-- 2. ГЕНЕРАТОР SEL (0 -> 1 -> 0 -> 1 ...)
-- =============================================
process(clk)
type state_type is (S0, S1);
variable state : state_type := S0;
variable counter : integer := 0;
constant DIVIDER : integer := 50000000; -- 1 Гц при 50 МГц
begin
if rising_edge(clk) then
if counter = DIVIDER - 1 then
counter := 0;
case state is
when S0 =>
sel <= '0';
state := S1;
when S1 =>
sel <= '1';
state := S0;
end case;
else
counter := counter + 1;
end if;
end if;
end process;
-- =============================================
-- 3. ВХОДНЫЕ МУЛЬТИПЛЕКСОРЫ
-- sel=0: на выходе 0
-- sel=1: на выходе A и B
-- =============================================
mux_a_out <= std_logic_vector(to_unsigned(A_VAL, 8)) when sel = '1' else (others => '0');
mux_b_out <= std_logic_vector(to_unsigned(B_VAL, 8)) when sel = '1' else (others => '0');
-- =============================================
-- 4. ТРИГГЕРЫ ДЛЯ A И B
-- Фиксируют значения на 1 такт
-- ПОДКЛЮЧЕНЫ К ОБОИМ УМНОЖИТЕЛЯМ!
-- =============================================
process(clk)
begin
if rising_edge(clk) then
a_reg <= mux_a_out; -- ← 0 или A
b_reg <= mux_b_out; -- ← 0 или B
end if;
end process;
-- =============================================
-- 5. DSP УМНОЖЕНИЕ (mult_5)
-- НА ВХОД ПРИХОДИТ a_reg И b_reg (0 или числа)
-- =============================================
mult_inst: mult_5
port map(
dataa => a_reg, -- ← 0 или A
datab => b_reg, -- ← 0 или B
result => dsp_result_vec
);
dsp_result_int <= to_integer(unsigned(dsp_result_vec));
-- =============================================
-- 6. ЛОГИЧЕСКОЕ УМНОЖЕНИЕ (logic)
-- НА ВХОД ПРИХОДИТ a_int И b_int (0 или числа)
-- =============================================
logic_inst: logic
port map(
a => a_int, -- ← 0 или A
b => b_int, -- ← 0 или B
result => logic_result
);
-- =============================================
-- 7. ОБРАБОТКА КНОПОК (выбор режима)
-- =============================================
process(clk)
begin
if rising_edge(clk) then
key_reg <= key;
key_prev <= key_reg;
if key_prev(0) = '1' and key_reg(0) = '0' then
mode <= '0'; -- Логическое умножение
elsif key_prev(1) = '1' and key_reg(1) = '0' then
mode <= '1'; -- DSP умножение
end if;
end if;
end process;
-- =============================================
-- 8. РЕГИСТР РЕЗУЛЬТАТА (выбор режима)
-- =============================================
process(clk)
begin
if rising_edge(clk) then
if mode = '0' then
result_reg <= logic_result; -- Логическое умножение
else
result_reg <= dsp_result_int; -- DSP умножение
end if;
trigger_reg <= '1';
end if;
end process;
-- =============================================
-- 9. ВЫХОДЫ
-- =============================================
result <= result_reg;
trigger <= trigger_reg;
end rtl;