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


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); 
	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);
	signal display_mode : std_logic_vector(7 downto 0);

begin

	U_OPERAND_INT: entity work.operand_init
		port map (
			clk=>clk,
			a_val=>a_val,
			b_val=>b_val
		);
	
	U_MODE_SELECT: entity work.mode_select
		port map (
			clk=>clk,
			key=> key,
			mode=>mode
		);
	
	U_MODE_DSIP: entity work.mode_display
		port map (
			clk=>clk,
			mode=>mode,
			mode_seg=>display_mode
		);

	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
		);

	U_MULT_DSP: entity work.mult_5
		port map (
			dataa => reg_a_out,
			datab => reg_b_out,
			result => dsp_result
		);

	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,
			mode_seg => display_mode,
			dig => dig,
			seg => seg
		);

end structural;


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(d0);
	seg_out(23 downto 16) <= digit_to_seg(d1);
	seg_out(15 downto 8)  <= digit_to_seg(d2);
	seg_out(7 downto 0)   <= digit_to_seg(d3);
	
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);
	mode_seg: in std_logic_vector(7 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 <= mode_seg;
			end case;
		end if;
	end process;
end rtl; 


library ieee;
use ieee.std_logic_1164.all;

entity mode_select is
port (
	clk  : in std_logic;
	key  : in std_logic_vector(2 downto 0);
	mode : out std_logic
);
end mode_select;

architecture rtl of mode_select is
begin
	process(clk)
	begin
		if rising_edge(clk) then
			if key(0) = '0' then
				mode <= '0';  -- По сбросу режим logic
			elsif key(1) = '0' then
				mode <= '0';  -- Режим logic
			elsif key(2) = '0' then
				mode <= '1';  -- Режим DSP
			end if;
		end if;
	end process;
end rtl;



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 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;




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 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;
use ieee.numeric_std.all;

entity logic is
port (
	a : in std_logic_vector(7 downto 0);
	b : in std_logic_vector(7 downto 0);
	result : out std_logic_vector(15 downto 0)
);
end logic;

architecture rtl of logic is
	signal a_int : integer;
	signal b_int : integer;
	signal res_int : integer;
begin
	a_int <= to_integer(unsigned(a));
	b_int <= to_integer(unsigned(b));
	res_int <= a_int * b_int;
	result <= std_logic_vector(to_unsigned(res_int, 16));
end rtl;




library ieee;
use ieee.std_logic_1164.all;

entity mode_display is
port (
	clk      : in std_logic;
	mode     : in std_logic;
	mode_seg : out std_logic_vector(7 downto 0)
);
end mode_display;

architecture rtl of mode_display is
begin
	process(clk)
	begin
		if rising_edge(clk) then
			if mode = '0' then
				mode_seg <= "11000111";  -- "L" для Logic
			else
				mode_seg <= "10100001";  -- "d" для DSP
			end if;
		end if;
	end process;
end rtl;



library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity operand_init is
port (
	clk   : in std_logic;
	a_val : out std_logic_vector(7 downto 0);
	b_val : out std_logic_vector(7 downto 0)
);
end operand_init;

architecture rtl of operand_init is
begin
			a_val <= "00000101";
			b_val <= "00000111";

end rtl;