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


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

entity timer is
    port (
        clk       : in  std_logic;
        pos_tick  : out std_logic
    );
end timer;

architecture rtl of timer is
    signal counter : integer range 0 to 50000000 := 0;
begin
    process(clk)
    begin
        if rising_edge(clk) then
            if counter = 50000000 - 1 then
                counter <= 0;
                pos_tick <= '1';
            else
                counter <= counter + 1;
                pos_tick <= '0';
            end if;
        end if;
    end process;
end rtl;

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

entity display_output is
    port (
        clk       : in  std_logic;
        pos_tick  : in  std_logic;
        char_0    : in  std_logic_vector(7 downto 0);
        char_1    : in  std_logic_vector(7 downto 0);
        char_2    : in  std_logic_vector(7 downto 0);
        char_3    : in  std_logic_vector(7 downto 0);
        position  : out integer range 0 to 15;  -- !!! ВЫХОД
        ind       : out std_logic_vector(3 downto 0);
        seg       : out std_logic_vector(7 downto 0)
    );
end display_output;

architecture rtl of display_output is
    signal pos_reg     : integer range 0 to 15 := 15;
    signal sel_dig     : integer range 0 to 3 := 0;
    signal mux_counter : integer range 0 to 100000 := 0;
begin

    -- Счётчик позиции (ВНУТРИ модуля дисплея)
    process(clk)
    begin
        if rising_edge(clk) then
            if pos_tick = '1' then
                if pos_reg = 0 then 
                    pos_reg <= 15;
                else 
                    pos_reg <= pos_reg - 1;
                end if;
            end if;
        end if;
    end process;
    
    position <= pos_reg;  -- Выводим позицию наружу

    process(clk)
    begin
        if rising_edge(clk) then
            if mux_counter = 100000 - 1 then
                mux_counter <= 0;
                if sel_dig = 3 then 
                    sel_dig <= 0;
                else 
                    sel_dig <= sel_dig + 1;
                end if;
            else
                mux_counter <= mux_counter + 1;
            end if;
        end if;
    end process;

    process(sel_dig, char_0, char_1, char_2, char_3)
    begin
        case sel_dig is
            when 0 =>
                ind <= "1110";
                seg <= char_0;
            when 1 =>
                ind <= "1101";
                seg <= char_1;
            when 2 =>
                ind <= "1011";
                seg <= char_2;
            when 3 =>
                ind <= "0111";
                seg <= char_3;
            when others =>
                ind <= "1111";
                seg <= "11111111";
        end case;
    end process;

end rtl;


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

entity sem_modul is
    port (
        clk     : in  std_logic;
        ind     : out std_logic_vector(3 downto 0);
        seg     : out std_logic_vector(7 downto 0)
    );
end sem_modul;

architecture rtl of sem_modul is

    type hex_array is array (0 to 15) of std_logic_vector(7 downto 0);
    
    constant hex_codes : hex_array := (
        "10001001",
        "10000110",
        "11000111",
        "10001100",
        "10111111",
        "11000111",
        "10001000",
        "00000000",
        "10011001",
        "11111111",
        "11111111",
        "11111111",
        "11111111",
        "11111111",
        "11111111",
        "11111111"
    );

    signal pos_tick    : std_logic;
    signal position    : integer range 0 to 15;  -- Принимаем из display
    signal char_0      : std_logic_vector(7 downto 0);
    signal char_1      : std_logic_vector(7 downto 0);
    signal char_2      : std_logic_vector(7 downto 0);
    signal char_3      : std_logic_vector(7 downto 0);

begin

    u_timer : entity work.timer
        port map (
            clk       => clk,
            pos_tick  => pos_tick
        );

    u_display : entity work.display_output
        port map (
            clk       => clk,
            pos_tick  => pos_tick,
            char_0    => char_0,
            char_1    => char_1,
            char_2    => char_2,
            char_3    => char_3,
            position  => position,  -- !!! Получаем позицию
            ind       => ind,
            seg       => seg
        );

    -- Вычисление символов (в топ модуле, т.к. алфавит здесь)
    char_0 <= hex_codes((position - 0) mod 16);
    char_1 <= hex_codes((position - 1) mod 16);
    char_2 <= hex_codes((position - 2) mod 16);
    char_3 <= hex_codes((position - 3) mod 16);

end rtl;