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


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;