Загрузка данных
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity calculator_top is
port (
clk : in std_logic;
key : in std_logic_vector(2 downto 0); -- key(0)=reset, key(1)=logic_mode, key(2)=dsp_mode
dig : out std_logic_vector(3 downto 0);
seg : out std_logic_vector(7 downto 0)
);
end calculator_top;
architecture structural of calculator_top is
-- Константы операндов
constant A_VAL : integer := 5;
constant B_VAL : integer := 7;
-- Сигналы данных
signal a_val : std_logic_vector(7 downto 0);
signal b_val : std_logic_vector(7 downto 0);
-- Сигналы управления
signal state : std_logic_vector(1 downto 0);
signal mult_en : std_logic;
signal save_en : std_logic;
signal mode : std_logic; -- '0' = logic, '1' = dsp
-- Сигналы тракта данных
signal mux_a_out : std_logic_vector(7 downto 0);
signal mux_b_out : std_logic_vector(7 downto 0);
signal reg_a_out : std_logic_vector(7 downto 0);
signal reg_b_out : std_logic_vector(7 downto 0);
-- Сигналы результатов
signal dsp_result : std_logic_vector(15 downto 0);
signal logic_result : std_logic_vector(15 downto 0);
signal selected_result : std_logic_vector(15 downto 0);
signal result_reg_out : std_logic_vector(15 downto 0);
-- Сигналы дисплея
signal display_data : std_logic_vector(31 downto 0);
begin
-- Присваиваем константы
a_val <= std_logic_vector(to_unsigned(A_VAL, 8));
b_val <= std_logic_vector(to_unsigned(B_VAL, 8));
-- Выбор режима: key(1)=logic, key(2)=dsp
-- Если ни одна не нажата - держим последний режим
process(clk, key(0))
begin
if key(0) = '0' then
mode <= '0'; -- По сбросу режим logic
elsif rising_edge(clk) then
if key(1) = '0' then
mode <= '0'; -- Режим logic
elsif key(2) = '0' then
mode <= '1'; -- Режим DSP
end if;
end if;
end process;
-- Управляющий автомат
U_CONTROL: entity work.mult_control
port map (
clk => clk,
reset => key(0),
mult_en => mult_en,
save_en => save_en,
state_out => state
);
-- Мультиплексор + регистр для A
U_MUX_REG_A: entity work.mux_register
port map (
clk => clk,
sel => mult_en,
data_a => a_val,
data_b => (others => '0'),
mux_out => mux_a_out,
q => reg_a_out
);
-- Мультиплексор + регистр для B
U_MUX_REG_B: entity work.mux_register
port map (
clk => clk,
sel => mult_en,
data_a => b_val,
data_b => (others => '0'),
mux_out => mux_b_out,
q => reg_b_out
);
-- DSP умножитель (mult_5)
U_MULT_DSP: entity work.mult_5
port map (
dataa => reg_a_out,
datab => reg_b_out,
result => dsp_result
);
-- Логический умножитель (logic)
U_MULT_LOGIC: entity work.logic
port map (
a => reg_a_out,
b => reg_b_out,
result => logic_result
);
-- Мультиплексор выбора результата
U_RESULT_MUX: entity work.result_mux
port map (
mode => mode,
logic_res => logic_result,
dsp_res => dsp_result,
result_out => selected_result
);
-- Регистр результата
U_RESULT_REG: entity work.result_register
port map (
clk => clk,
load => save_en,
data_in => selected_result,
data_out => result_reg_out
);
-- Преобразователь в дисплей
U_BIN_TO_DISP: entity work.bin_to_display
port map (
bin_in => result_reg_out,
seg_out => display_data
);
-- Сканер дисплея
U_DISPLAY: entity work.display_scan
port map (
clk => clk,
seg_in => display_data,
dig => dig,
seg => seg
);
end structural;
library ieee;
use ieee.std_logic_1164.all;
entity mult_control is
port (
clk : in std_logic;
reset : in std_logic;
mult_en : out std_logic;
save_en : out std_logic;
state_out : out std_logic_vector(1 downto 0)
);
end mult_control;
architecture rtl of mult_control is
signal counter : integer range 0 to 49999999 := 0;
constant ONE_SEC : integer := 50000000;
type state_type is (IDLE, MULT, SAVE, HOLD);
signal state : state_type := IDLE;
begin
process(clk)
begin
if rising_edge(clk) then
if reset = '0' then
state <= IDLE;
counter <= 0;
else
case state is
when IDLE =>
mult_en <= '0';
save_en <= '0';
if counter >= ONE_SEC - 1 then
counter <= 0;
state <= MULT;
else
counter <= counter + 1;
end if;
when MULT =>
mult_en <= '1';
save_en <= '0';
state <= SAVE;
when SAVE =>
mult_en <= '0';
save_en <= '1';
state <= HOLD;
when HOLD =>
mult_en <= '0';
save_en <= '0';
if counter >= ONE_SEC - 1 then
counter <= 0;
state <= MULT;
else
counter <= counter + 1;
end if;
end case;
end if;
end if;
end process;
with state select
state_out <= "00" when IDLE,
"01" when MULT,
"10" when SAVE,
"11" when HOLD;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity display_scan is
port (
clk : in std_logic;
seg_in : in std_logic_vector(31 downto 0);
dig : out std_logic_vector(3 downto 0);
seg : out std_logic_vector(7 downto 0)
);
end display_scan;
architecture rtl of display_scan is
signal scan_counter : integer range 0 to 49999 := 0;
signal sel_dig : integer range 0 to 3 := 0;
begin
process(clk)
begin
if rising_edge(clk) then
if scan_counter >= 49999 then
scan_counter <= 0;
if sel_dig = 3 then
sel_dig <= 0;
else
sel_dig <= sel_dig + 1;
end if;
else
scan_counter <= scan_counter + 1;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
case sel_dig is
when 0 =>
dig <= "1110";
seg <= seg_in(31 downto 24);
when 1 =>
dig <= "1101";
seg <= seg_in(23 downto 16);
when 2 =>
dig <= "1011";
seg <= seg_in(15 downto 8);
when 3 =>
dig <= "0111";
seg <= seg_in(7 downto 0);
when others =>
dig <= "1111";
seg <= "11111111";
end case;
end if;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bin_to_display is
port (
bin_in : in std_logic_vector(15 downto 0);
seg_out : out std_logic_vector(31 downto 0)
);
end bin_to_display;
architecture rtl of bin_to_display is
function digit_to_seg(digit : integer) return std_logic_vector is
begin
case digit is
when 0 => return "11000000";
when 1 => return "11111001";
when 2 => return "10100100";
when 3 => return "10110000";
when 4 => return "10011001";
when 5 => return "10010010";
when 6 => return "10000010";
when 7 => return "11111000";
when 8 => return "10000000";
when 9 => return "10010000";
when others => return "11111111";
end case;
end function;
signal value : integer;
signal d3, d2, d1, d0 : integer;
begin
value <= to_integer(unsigned(bin_in));
d3 <= (value / 1000) mod 10;
d2 <= (value / 100) mod 10;
d1 <= (value / 10) mod 10;
d0 <= value mod 10;
seg_out(31 downto 24) <= digit_to_seg(d3);
seg_out(23 downto 16) <= digit_to_seg(d2);
seg_out(15 downto 8) <= digit_to_seg(d1);
seg_out(7 downto 0) <= digit_to_seg(d0);
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity result_mux is
port (
mode : in std_logic;
logic_res : in std_logic_vector(15 downto 0);
dsp_res : in std_logic_vector(15 downto 0);
result_out : out std_logic_vector(15 downto 0)
);
end result_mux;
architecture rtl of result_mux is
begin
result_out <= logic_res when mode = '0' else dsp_res;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity mode_select is
port (
clk : in std_logic;
key : in std_logic;
mode : out std_logic;
mode_out : out std_logic_vector(7 downto 0) -- Для Signal Tap
);
end mode_select;
architecture rtl of mode_select is
signal mode_reg : std_logic := '0';
signal key_prev : std_logic := '1';
begin
process(clk)
begin
if rising_edge(clk) then
key_prev <= key;
-- Переключение режима по нажатию кнопки
if key_prev = '1' and key = '0' then
mode_reg <= not mode_reg;
end if;
end if;
end process;
mode <= mode_reg;
mode_out <= "0000000" & mode_reg; -- Для удобного просмотра
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity result_register is
port (
clk : in std_logic;
load : in std_logic;
data_in : in std_logic_vector(15 downto 0);
data_out : out std_logic_vector(15 downto 0)
);
end result_register;
architecture rtl of result_register is
signal reg_data : std_logic_vector(15 downto 0) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
if load = '1' then
reg_data <= data_in;
end if;
end if;
end process;
data_out <= reg_data;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity mux_register is
port (
clk : in std_logic;
sel : in std_logic;
data_a : in std_logic_vector(7 downto 0);
data_b : in std_logic_vector(7 downto 0);
mux_out : out std_logic_vector(7 downto 0);
q : out std_logic_vector(7 downto 0)
);
end mux_register;
architecture rtl of mux_register is
signal mux_signal : std_logic_vector(7 downto 0);
signal reg_signal : std_logic_vector(7 downto 0) := (others => '0');
begin
-- Мультиплексор
mux_signal <= data_a when sel = '1' else data_b;
-- Регистр
process(clk)
begin
if rising_edge(clk) then
reg_signal <= mux_signal;
end if;
end process;
-- Выходы
mux_out <= mux_signal;
q <= reg_signal;
end rtl;