Загрузка данных
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity display_control is
generic
(
SCAN_RATE : integer := 100000
);
port
(
clk : in std_logic;
reset : in std_logic;
dig : out std_logic_vector(3 downto 0);
seg : out std_logic_vector(7 downto 0);
dig0 : in std_logic_vector(7 downto 0);
dig1 : in std_logic_vector(7 downto 0);
dig2 : in std_logic_vector(7 downto 0);
dig3 : in std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of display_control is
signal scan_counter: integer:=0;
signal sel_dig: integer range 0 to 3:=0;
begin
-- сканер разрядов (динамическая индикация)
process(clk)
begin
if reset = '1' then
scan_counter <= 0;
sel_dig<=0;
elsif rising_edge(clk) then
if scan_counter >= SCAN_RATE - 1 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(sel_dig, dig0, dig1, dig2, dig3)
begin
case sel_dig is
when 0 =>
dig <= "1110";
seg <= dig0;
when 1 =>
dig <= "1101";
seg <= dig1;
when 2 =>
dig <= "1011";
seg <= dig2;
when 3 =>
dig <= "0111";
seg <= dig3;
when others =>
dig <= "1111";
seg <= "11111111";
end case;
end process;
end rtl;
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);
signal a_reg : std_logic_vector(7 downto 0) := (others => '0');
signal b_reg : std_logic_vector(7 downto 0) := (others => '0');
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
a_int <= to_integer(unsigned(a_reg));
b_int <= to_integer(unsigned(b_reg));
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;
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');
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;
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));
logic_inst: logic
port map(
a => a_int, -- ← 0 или A
b => b_int, -- ← 0 или B
result => logic_result
);
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;
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;
result <= result_reg;
trigger <= trigger_reg;
end rtl;
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(3 downto 0);
dig : out std_logic_vector(3 downto 0);
seg : out std_logic_vector(7 downto 0)
);
end entity;
architecture struct of calculator_top is
signal c0,c1,c2,c3:std_logic_vector(7 downto 0);
signal calc_result: integer:=0;
signal calc_trigger: std_logic:='0';
signal display_result: integer:=0;
component calculator is
port(
clk : in std_logic;
key : in std_logic_vector(1 downto 0);
result : out integer;
trigger : out std_logic
);
end component;
component display_control is
port(
clk : in std_logic;
reset : in std_logic;
dig : out std_logic_vector(3 downto 0);
seg : out std_logic_vector(7 downto 0);
dig0 : in std_logic_vector(7 downto 0);
dig1 : in std_logic_vector(7 downto 0);
dig2 : in std_logic_vector(7 downto 0);
dig3 : in std_logic_vector(7 downto 0)
);
end component;
function num_to_seg(num:integer)return std_logic_vector is
begin
case num 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;
begin
calc_inst: calculator
port map(
clk=>clk,
key=>key(1 downto 0),
result=>calc_result,
trigger=>calc_trigger
);
process(clk)
begin
if rising_edge(clk) then
if calc_trigger='1' then
display_result<=calc_result;
end if;
end if;
end process;
process(display_result)
variable tens, ones : integer;
begin
if display_result>=0 and display_result <= 99 then
tens := display_result / 10;
ones := display_result mod 10;
c3 <= num_to_seg(tens);
c2 <= num_to_seg(ones);
c1 <= "11111111"; -- Гасим неиспользуемые
c0 <= "11111111";
else
c3 <= "11111111";
c2 <= "11111111";
c1 <= "11111111";
c0 <= "11111111";
end if;
end process;
display_inst: entity work.display_control
port map (
clk => clk,
reset=>'0',
seg => seg,
dig => dig,
dig0 => c0,
dig1 => c1,
dig2 => c2,
dig3 => c3
);
end struct;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity logic is
port
(
a :in integer;
b :in integer;
result : out integer
);
end logic;
architecture rtl of logic is
begin
result<=a*b;
end rtl;