Загрузка данных


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;