Přeskočit obsah

Číslicová technika

Číslicová technika představuje základní kurz zaměřený na principy fungování digitálních systémů. Studenti se seznámí s tím, jak jsou na nejnižší úrovni reprezentována data a jak probíhají logické operace v procesorech a dalších digitálních obvodech.

Základní informace

  • Katedra: Katedra mechatroniky a počítačového řízení (KMP)
  • Zakončení: Zápočet + Zkouška
  • Forma výuky: Přednášky a praktické laboratorní cvičení

Obsah předmětu

Kurz pokrývá cestu od základních logických členů až po složitější sekvenční obvody:

  1. Číselné soustavy a kódy: Binární, hexadecimální soustava, doplňkový kód, BCD kód a Grayův kód.
  2. Booleova algebra: Logické operace (AND, OR, NOT, NAND, NOR, XOR), minimalizace logických funkcí pomocí Karnaughových map.
  3. Kombinační logické obvody: Kodéry, dekodéry, multiplexory, demultiplexory, sčítačky a komparátory.
  4. Sekvenční logické obvody: Klopné obvody (RS, D, JK, T), registry, čítače a synchronní automaty.
  5. Paměti a programovatelná logika: Typy pamětí (ROM, RAM) a základy struktur typu FPGA/CPLD.

Podmínky zakončení

Zápočet

Zápočet se získává především za práci v laboratořích:

  • Laboratorní úlohy: Praktické zapojování obvodů na nepájivém poli nebo simulace v softwaru.
  • Protokoly: Zpracování výsledků z měření a simulací v předepsané formě.
  • Kontrolní testy: Teoretické testy v průběhu semestru zaměřené na návrh a minimalizaci obvodů.

Zkouška

Zkouška prověřuje schopnost navrhnout konkrétní digitální zařízení:

  • Písemná část: Návrh kombinačních a sekvenčních obvodů (např. navrhnout čítač nebo automat, který rozpoznává sekvenci bitů).
  • Ústní část: Diskuse nad principy, technologiemi výroby integrovaných obvodů a architekturou číslicových systémů.

[Image of a logic circuit diagram with AND, OR and NOT gates]

Doporučení a tipy

  • Karnaughovy mapy: Naučte se je perfektně. Jsou základem pro většinu příkladů u zkoušky i v testech.
  • Laboratoře nepodceňujte: Pokud si v laboratořích osaháte reálné součástky, teorie z přednášek vám začne dávat mnohem větší smysl.
  • Logika: Předmět nevyžaduje složité výpočty jako Matematika 2, ale vyžaduje logické a analytické myšlení.
  • Software: Často se využívají simulační nástroje (např. Logisim, Multisim nebo Quartus), které vám umožní si obvody nasimulovat i doma.

Přehled výuky

Skripta

Přednášky

1. Hradla

2. Booleova algebra

3. Používané logické funkce a jejich popis ve VHDL

3. Používané logické funkce a jejich popis ve VHDL - příklady

4. Klopné obvody

5. Sekvenční logické systémy a automaty

6. Jazyky popisující hardware

7. Binární čítače a paměti

8a. Paměti a aritmetické obvody

8b. Zákaznické obvody

9. Procesory, mikroprocesory, procesory na FPGA

10. Paměťový podsystém

Cvičení

1. Hradla

2. Booleova algebra

3. Vivado, VHDL jazyk

4. Podmíněné přiřazení, multiplexor

4. Podmíněné přiřazení, multiplexor

multiplexory.vhd

-- 1. Strukturní popis pomocí logických hradel pro výstup q_struct
q_struct <= (a and not sel) or (b and sel);

-- 2. Behaviorální popis pomocí podmíněného přiřazení pro výstup q_condition
q_condition <= a when sel = '0' else b;


-- a. Na první dvě diody přiřaďte log. 0 (použití agregátu)
LEDs(1 downto 0) <= (others => '0');

-- b. Na diody 2 a 3 přiřaďte log. 1
LEDs(3 downto 2) <= "11";

-- c. Na další 4 diody přiřaďte první čtyři přepínače
LEDs(7 downto 4) <= switches(3 downto 0);

-- d. Na posledních 8 diod přiřaďte 4 přepínače (z obrázku switches 15 až 12) pomocí operátoru slučování '&'
LEDs(15 downto 8) <= switches(15) & switches(15) & switches(14) & switches(14) & switches(13) & switches(13) & switches(12) & switches(12);

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity multiplexor is
    Port (
           d : in STD_LOGIC_VECTOR (7 downto 0); -- Vstupní datový port
           s : in STD_LOGIC_VECTOR (2 downto 0); -- Výběrový vstupní port
           q : out STD_LOGIC                     -- Výstupní port
         );
end multiplexor;

architecture Behavioral of multiplexor is
begin
    -- Podmíněné přiřazení pro 8-vstupý multiplexor
    q <= d(0) when s = "000" else
         d(1) when s = "001" else
         d(2) when s = "010" else
         d(3) when s = "011" else
         d(4) when s = "100" else
         d(5) when s = "101" else
         d(6) when s = "110" else
         d(7); -- Poslední větev 'else' bez podmínky
end Behavioral;

5. Výběrové přiřazení, dekodéry

decoder.vhd

-- Výběrové přiřazení pro dekodér 2 na 4
    with d select q <=
        "0001" when "00",
        "0010" when "01",
        "0100" when "10",
        "1000" when others; -- 'others' pokrývá stav "11" a slouží jako pojistka

displays.vhd

-- 1. Dekodér pro výběr konkrétního displeje (výstup displays, 8 bitů)
    -- Vybíráme jeden z 8 displejů. Vybraný displej má '0', ostatní '1' (negativní výstup).
    with disp_sel select displays <=
        "11111110" when "000", -- Rozsvítí nejvíce pravý displej
        "11111101" when "001",
        "11111011" when "010",
        "11110111" when "011",
        "11101111" when "100",
        "11011111" when "101",
        "10111111" when "110",
        "01111111" when others; -- "111" (nejvíce levý displej)

    -- 2. Dekodér pro znaky na 7-segmentovém displeji (výstup segments, 8 bitů)
    -- Pořadí segmentů je: DP, G, F, E, D, C, B, A
    -- 0 znamená, že daný segment svítí!
    with char_sel select segments <=
        "11000000" when "0000", -- Znak 0 (nesvítí jen G a DP)
        "11111001" when "0001", -- Znak 1 (svítí B, C)
        "10100100" when "0010", -- Znak 2
        "10110000" when "0011", -- Znak 3
        "10011001" when "0100", -- Znak 4
        "10010010" when "0101", -- Znak 5
        "10000010" when "0110", -- Znak 6
        "11111000" when "0111", -- Znak 7
        "10000000" when "1000", -- Znak 8 (svítí vše kromě DP)
        "10010000" when "1001", -- Znak 9
        "10001000" when "1010", -- Znak A
        "10000011" when "1011", -- Znak b
        "11000110" when "1100", -- Znak C
        "10100001" when "1101", -- Znak d
        "10000110" when "1110", -- Znak E
        "10001110" when others; -- Znak F ("1111")

6. Výběrové přiřazení, dekodéry

multiplexor.vhd

process(d, s) -- Citlivostní seznam obsahuje oba vstupy
begin
    if s = "00" then
        q <= d(0);
    elsif s = "01" then
        q <= d(1);
    elsif s = "10" then
        q <= d(2);
    else
        q <= d(3);
    end if;
end process;

multiplexor_tb.vhd

process
begin
    -- Počáteční stav
    mux_d <= "0000";

    -- Test pro vstup d(0)
    mux_s <= "00";
    wait for 10 ns;
    mux_d <= "0001"; -- d(0) jde do 1
    wait for 10 ns;

    -- Test pro vstup d(1)
    mux_s <= "01";
    mux_d <= "0000"; -- reset vstupů
    wait for 10 ns;
    mux_d <= "0010"; -- d(1) jde do 1
    wait for 10 ns;

    -- Test pro vstup d(2)
    mux_s <= "10";
    mux_d <= "0000";
    wait for 10 ns;
    mux_d <= "0100"; -- d(2) jde do 1
    wait for 10 ns;

    -- Test pro vstup d(3)
    mux_s <= "11";
    mux_d <= "0000";
    wait for 10 ns;
    mux_d <= "1000"; -- d(3) jde do 1
    wait for 10 ns;

    wait; -- Zastavení simulace
end process;

decoder.vhd

process(d) -- Vstupní signál v citlivostním seznamu
begin
    case d is
        when "00" => q <= "0001";
        when "01" => q <= "0010";
        when "10" => q <= "0100";
        when others => q <= "1000"; -- 'others' pokryje stav "11" a další stavy jako 'U', 'X' atd.
    end case;
end process;

decoder_tb.vhd

architecture Behavioral of decoder_tb is
    -- Deklarace signálů s inicializací
    signal dec_d : std_logic_vector(1 downto 0) := (others => '0');
    signal dec_q : std_logic_vector(3 downto 0);
begin
    -- Instance testovaného obvodu
    dec_inst: entity work.decoder
        port map(
            d => dec_d,
            q => dec_q
        );

    -- Proces pro buzení vstupů
    process
    begin
        dec_d <= "00"; wait for 10 ns;
        dec_d <= "01"; wait for 10 ns;
        dec_d <= "10"; wait for 10 ns;
        dec_d <= "11"; wait for 10 ns;
        wait;
    end process;
end Behavioral;

top.vhd

-- Příklad namapování
-- Společná data pro MUXy na přepínačích 0 až 3
-- Výběr MUX1 na přepínačích 4, 5
-- Výběr MUX2 na přepínačích 6, 7
mux1_inst: entity work.multiplexor
    port map(
        d => SW(3 downto 0),
        s => SW(5 downto 4),
        q => LEDs(0)
    );

mux2_inst: entity work.multiplexor
    port map(
        d => SW(3 downto 0), -- Sdílené datové vstupy
        s => SW(7 downto 6), -- Rozdílné vstupy výběru
        q => LEDs(1)
    );

-- Podobně instancuješ i dec1_inst a dec2_inst na další volné SW a LEDs

7a. Registry

simple_reg.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity simple_reg is
    Port (
        clock       : in  STD_LOGIC;
        reset       : in  STD_LOGIC;
        data        : in  STD_LOGIC;
        enable      : in  STD_LOGIC;
        q_ff_re     : out STD_LOGIC;
        q_latch     : out STD_LOGIC;
        q_ff_re_sr  : out STD_LOGIC;
        q_ff_fe_ar  : out STD_LOGIC
    );
end simple_reg;

architecture Behavioral of simple_reg is
    -- Deklarace signálů s různými výchozími hodnotami podle zadání
    signal ff_re      : std_logic := '1';
    signal s_latch    : std_logic := '0';
    signal s_ff_re_sr : std_logic := '1';
    signal s_ff_fe_ar : std_logic := '0';

begin

    -- =========================================================
    -- 2. Základní klopný obvod typu D (Z předlohy)
    -- =========================================================
    process (clock)
    begin
        if rising_edge(clock) then
            ff_re <= data;
        end if;
    end process;
    q_ff_re <= ff_re;

    -- =========================================================
    -- 4a. Hladinový klopný obvod (Latch) s asynch. resetem
    -- =========================================================
    process (clock, reset, data)
    begin
        if reset = '1' then
            s_latch <= '0';
        elsif clock = '1' then
            s_latch <= data;
        end if;
    end process;
    q_latch <= s_latch;

    -- =========================================================
    -- 4b. Hranový (náběžná) D-FF se synchronním resetem a enable
    -- =========================================================
    process (clock)
    begin
        if rising_edge(clock) then
            if reset = '1' then
                s_ff_re_sr <= '0';
            elsif enable = '1' then
                s_ff_re_sr <= data;
            end if;
        end if;
    end process;
    q_ff_re_sr <= s_ff_re_sr;

    -- =========================================================
    -- 4c. Hranový (sestupná) D-FF s asynchronním resetem a enable
    -- =========================================================
    process (clock, reset)
    begin
        if reset = '1' then
            s_ff_fe_ar <= '0';
        elsif falling_edge(clock) then
            if enable = '1' then
                s_ff_fe_ar <= data;
            end if;
        end if;
    end process;
    q_ff_fe_ar <= s_ff_fe_ar;

end Behavioral;

simple_regs_tb.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity simple_regs_tb is
end simple_regs_tb;

architecture behavior of simple_regs_tb is

    -- Definice komponenty, kterou testujeme
    component simple_reg
    port(
         clock      : in std_logic;
         reset      : in std_logic;
         data       : in std_logic;
         enable     : in std_logic;
         q_ff_re    : out std_logic;
         q_latch    : out std_logic;
         q_ff_re_sr : out std_logic;
         q_ff_fe_ar : out std_logic
        );
    end component;

    -- Vstupní signály (s výchozími stavy)
    signal clock  : std_logic := '0';
    signal reset  : std_logic := '0';
    signal data   : std_logic := '1';
    signal enable : std_logic := '1';

    -- Výstupní signály
    signal q_ff_re    : std_logic;
    signal q_latch    : std_logic;
    signal q_ff_re_sr : std_logic;
    signal q_ff_fe_ar : std_logic;

    -- Definice periody hodin (podle grafu v PDF odpovídá jeden cyklus 20 ns)
    constant clk_period : time := 20 ns;

begin

    -- Připojení (namapování) testovaného obvodu (UUT)
    uut: simple_reg port map (
          clock      => clock,
          reset      => reset,
          data       => data,
          enable     => enable,
          q_ff_re    => q_ff_re,
          q_latch    => q_latch,
          q_ff_re_sr => q_ff_re_sr,
          q_ff_fe_ar => q_ff_fe_ar
        );

    -- Proces, který generuje nekonečné hodiny (0, 1, 0, 1...)
    clk_process :process
    begin
        clock <= '0';
        wait for clk_period/2;
        clock <= '1';
        wait for clk_period/2;
    end process;

    -- Proces pro generování dat, resetu a enable podle průběhů z grafu
    stim_proc: process
    begin
        -- Počáteční stavy (čas 0 ns)
        reset  <= '0';
        enable <= '1';
        data   <= '1';

        wait for 20 ns;
        data <= '0';

        wait for 20 ns;
        data <= '1';

        -- Rychlé překlopení dat kolem času 45-50 ns
        wait for 5 ns;
        data <= '0';
        wait for 5 ns;
        data <= '1';

        wait for 15 ns;  -- Čas 65 ns
        enable <= '0';
        data   <= '0';

        wait for 20 ns;  -- Čas 85 ns
        enable <= '1';

        wait for 15 ns;  -- Čas 100 ns
        reset <= '1';

        wait for 5 ns;   -- Čas 105 ns
        reset <= '0';

        wait for 20 ns;  -- Čas 125 ns
        reset <= '1';

        -- Ukončení změn
        wait;
    end process;

end behavior;

7b. Posuvný registr / sériová komunikace, Johnsonův čítač, LFSR

shift_reg.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity shift_reg is
    Port (
        clock          : in  STD_LOGIC;
        shift_not_load : in  STD_LOGIC;
        serial_in      : in  STD_LOGIC;
        data_in        : in  STD_LOGIC_VECTOR (7 downto 0);
        serial_out     : out STD_LOGIC;
        data_out       : out STD_LOGIC_VECTOR (7 downto 0)
    );
end shift_reg;

architecture Behavioral of shift_reg is
    -- Vnitřní paměť registru (počáteční stav samé nuly)
    signal s_reg : std_logic_vector(7 downto 0) := (others => '0');
begin

    process(clock)
    begin
        if rising_edge(clock) then
            if shift_not_load = '0' then
                -- Paralelní nahrání dat (Load)
                s_reg <= data_in;
            else
                -- Posun doprava (Shift): na pozici 7 jde serial_in, zbytek se posune o 1 dolů
                s_reg <= serial_in & s_reg(7 downto 1);
            end if;
        end if;
    end process;

    -- Výstupy jsou asynchronně připojené přímo na vnitřní signál
    serial_out <= s_reg(0); -- Nejnižší bit vypadává ven jako serial_out
    data_out   <= s_reg;

end Behavioral;

johnson_count.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity johnson_count is
    Port (
        clock      : in  STD_LOGIC;
        reset      : in  STD_LOGIC;
        q_johnson  : out STD_LOGIC_VECTOR (3 downto 0);
        q_binary   : out STD_LOGIC_VECTOR (2 downto 0)
    );
end johnson_count;

architecture Behavioral of johnson_count is
    signal s_reg : std_logic_vector(3 downto 0) := (others => '0');
begin

    -- Sekvenční proces (paměť) - samotný čítač
    process(clock)
    begin
        if rising_edge(clock) then
            if reset = '1' then
                s_reg <= "0000"; -- Synchronní reset vynuluje registr
            else
                -- Posun doprava s negovanou zpětnou vazbou
                s_reg <= not s_reg(0) & s_reg(3 downto 1);
            end if;
        end if;
    end process;

    q_johnson <= s_reg;

    -- Kombinační proces - Dekodér do binárního kódu
    process(s_reg)
    begin
        case s_reg is
            when "0000" => q_binary <= "000"; -- 0
            when "1000" => q_binary <= "001"; -- 1
            when "1100" => q_binary <= "010"; -- 2
            when "1110" => q_binary <= "011"; -- 3
            when "1111" => q_binary <= "100"; -- 4
            when "0111" => q_binary <= "101"; -- 5
            when "0011" => q_binary <= "110"; -- 6
            when "0001" => q_binary <= "111"; -- 7
            when others => q_binary <= "000"; -- Pojistka pro neplatné stavy
        end case;
    end process;

end Behavioral;

LFSR.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity LFSR is
    Port (
        clock : in  STD_LOGIC;
        load  : in  STD_LOGIC;
        SW    : in  STD_LOGIC_VECTOR (15 downto 0);
        LED   : out STD_LOGIC_VECTOR (15 downto 0)
    );
end LFSR;

architecture Behavioral of LFSR is
    -- Pozor: LFSR nesmí nikdy začít v samých nulách, jinak se zasekne!
    signal s_reg    : std_logic_vector(15 downto 0) := x"0001";
    signal feedback : std_logic;
begin

    -- Zpětná vazba vypočítaná z bitů 5, 3, 2 a 0 pomocí XOR
    feedback <= s_reg(5) xor s_reg(3) xor s_reg(2) xor s_reg(0);

    process(clock)
    begin
        if rising_edge(clock) then
            if load = '1' then
                s_reg <= SW; -- Nahrání hodnoty z přepínačů
            else
                -- Posun doprava, na pozici 15 se nasune vypočítaná zpětná vazba
                s_reg <= feedback & s_reg(15 downto 1);
            end if;
        end if;
    end process;

    LED <= s_reg;

end Behavioral;

8. Čítače, generické parametry, děličky hodin, detekce tlačítka

counter.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter is
    generic(
        COUNTER_WIDTH : integer := 4
    );
    port(
        clock        : in  std_logic;   -- 100 MHz clock
        cnt          : out std_logic_vector(COUNTER_WIDTH - 1 downto 0); -- counter output
        --
        reset        : in  std_logic;   -- positive reset
        clock_enable : in  std_logic;   -- clock enable
        limit        : in  std_logic_vector(COUNTER_WIDTH - 1 downto 0);
        repeat       : in  std_logic;   -- repeat when finished
        done         : out std_logic    -- counter reached limit
    );
end counter;

architecture Behavioral of counter is

    signal counter_reg : unsigned(COUNTER_WIDTH - 1 downto 0);

begin

    process(clock)
    begin
        if rising_edge(clock) then
            if reset = '1' then
                counter_reg <= (others => '0');
            elsif clock_enable = '1' then
                if counter_reg >= unsigned(limit) then
                    if repeat = '1' then
                        counter_reg <= (others => '0');
                    end if;
                else
                    counter_reg <= counter_reg + 1;
                end if;
            end if;
        end if;
    end process;

    cnt <= std_logic_vector(counter_reg);
    done <= '1' when counter_reg >= unsigned(limit) else '0';


end Behavioral;

counter_tb.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter_tb is
end counter_tb;

architecture Behavioral of counter_tb is

    constant SIM_WIDTH : integer := 4;
    constant CLK_PERIOD : time := 10 ns;

    signal clock : std_logic := '1';

    -- inputs
    signal reset        : std_logic                                := '0';
    signal clock_enable : std_logic                                := '0';
    signal limit        : std_logic_vector(SIM_WIDTH - 1 downto 0) := std_logic_vector(to_unsigned(7, SIM_WIDTH));
    signal repeat       : std_logic                                := '0';

    signal cnt : std_logic_vector(SIM_WIDTH - 1 downto 0);
    signal done         : std_logic;

begin

    clock <= not clock after CLK_PERIOD / 2;

    DUT : entity work.counter
        generic map(
            COUNTER_WIDTH => SIM_WIDTH
        )
        port map(
            clock        => clock,
            cnt          => cnt,
            reset        => reset,
            clock_enable => clock_enable,
            limit        => limit,
            repeat       => repeat,
            done         => done
        );

    tb : process
    begin
        reset <= '1';
        wait for CLK_PERIOD;
        reset <= '0';
        wait for CLK_PERIOD * 2;
        clock_enable <= '1';
        wait;

    end process;


end Behavioral;

debounce.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;

entity debounce is
    port(
        clock        : in  std_logic;
        button       : in  std_logic;
        pressed      : out std_logic
    );
end debounce;

architecture Behavioral of debounce is

    -- change values to create 100 Hz pulses.
    constant DIV100HZ_WIDTH : integer := 20;
    constant DIV100HZ_LIMIT : integer := 999999;

    signal div100Hz_done : std_logic;

    signal last_button_value : std_logic;
    signal actual_button_value : std_logic;

begin

    clock_div : entity work.counter
        generic map(
            COUNTER_WIDTH => DIV100HZ_WIDTH
        )
        port map(
            clock        => clock,
            cnt          => open,
            reset        => '0',
            clock_enable => '1',
            limit        => std_logic_vector(to_unsigned(DIV100HZ_LIMIT, DIV100HZ_WIDTH)),
            repeat       => '1',
            done         => div100Hz_done
        );

    -- register updates each 100 ms
    process(clock)
    begin
        if rising_edge(clock) then
            if div100Hz_done = '1' then
                actual_button_value <= button;
                last_button_value <= actual_button_value;
            end if;
        end if;
    end process;

    process(clock)
    begin
        if rising_edge(clock) then
            pressed <= '0';
            if div100Hz_done = '1' then
                -- detect rising edge or falling edge
                if actual_button_value = '1' and last_button_value = '0' then
                    pressed <= '1';
                end if;
            end if;
        end if;
    end process;

end Behavioral;

top.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity top is
    port(
        clock                                             : in  std_logic;
        btn_up, btn_right, btn_down, btn_left, btn_center : in  std_logic;
        SW                                                : in  std_logic_vector(15 downto 0);
        LED                                               : out std_logic_vector(15 downto 0);
        LED_BLUE                                          : out std_logic;
        --for du
        segments                                          : out std_logic_vector(7 downto 0);
        displays                                          : out std_logic_vector(7 downto 0)
    );
end top;

architecture Behavioral of top is

    constant BOARD_WIDTH : integer                                    := 16;
    signal limit         : std_logic_vector(BOARD_WIDTH - 1 downto 0) := (others => '0');
    signal s_pressed     : std_logic;

    --for du
    signal s_count : std_logic_vector(15 downto 0);
    --signal s_din   : std_logic_vector(31 downto 0);

begin
    --for du
    --LED <= s_count;
    --s_din <= X"0000" & s_count;
    counter_sixteen : entity work.counter
        generic map(
            COUNTER_WIDTH => BOARD_WIDTH
        )
        port map(
            clock        => clock,
            cnt          => LED,
            --for du
            --cnt            => s_count,
            reset        => btn_right,
            clock_enable => s_pressed,
            limit        => SW,
            repeat       => btn_down,
            done         => LED_BLUE
        );

    debounce_inst : entity work.debounce
        port map(
              clock        => clock,
               -- connect to a button of your choice
              button       => btn_up,
              -- create a signal and connect it to the clock_enable port of the counter above
              pressed      => s_pressed
        );

    --for du
    display_driver_inst : entity work.display_driver
        port map(
            din         => X"0000" & s_count,
            --din       => s_din,
            segments    => segments,
            displays    => displays,
            clock       => clock,
            reset       => btn_center
        );

end Behavioral;

display_driver.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity display_driver is
    port(
        clock    : in  std_logic;
        reset    : in  std_logic;
        din      : in  std_logic_vector(31 downto 0);
        segments : out std_logic_vector(7 downto 0);
        displays : out std_logic_vector(7 downto 0)
    );
end display_driver;

architecture Behavioral of display_driver is

    constant C_10KHZ_WIDTH : integer := 14;
    constant C_10KHZ_LIMIT : integer := 9999;

    signal s_en_10khz : std_logic;
    signal s_cnt_3bit : unsigned(2 downto 0);

    signal s_hex : std_logic_vector(3 downto 0);

begin

    clk_div_i : entity work.counter
        generic map (
            COUNTER_WIDTH => C_10KHZ_WIDTH
        )
        port map(
            clock        => clock,
            cnt          => open,
            reset        => '0',
            clock_enable => '1',
            limit        => std_logic_vector(to_unsigned(C_10KHZ_LIMIT, C_10KHZ_WIDTH)),
            repeat       => '1',
            done         => s_en_10khz
        );


    process(clock)
    begin
        if rising_edge(clock) then
            if reset = '1' then
                s_cnt_3bit <= "000";
            elsif s_en_10khz = '1' then
                s_cnt_3bit <= s_cnt_3bit + 1;
            end if;
        end if;
    end process;

    --multiplexor
    process(s_cnt_3bit,din)
    begin
        case s_cnt_3bit is
            when "000" =>
            s_hex <= din(3 downto 0);
            displays <= "11111110";
            when "001" =>
            s_hex <= din(7 downto 4);
            displays <= "11111101";
            when "010" =>
            s_hex <= din(11 downto 8);
            displays <= "11111011";
            when "011" =>
            s_hex <= din(15 downto 12);
            displays <= "11110111";
            when "100" =>
            s_hex <= din(19 downto 16);
            displays <= "11101111";
            when "101" =>
            s_hex <= din(23 downto 20);
            displays <= "11011111";
            when "110" =>
            s_hex <= din(27 downto 24);
            displays <= "10111111";
            when others =>
            s_hex <= din(31 downto 28);
            displays <= "01111111";
        end case;
    end process;

    --decoder
    process(s_hex)
    begin
        --DP G F E D C B A
        case s_hex is
            when X"0" =>
            segments <= "11000000";
            when X"1" =>
            segments <= "11111001";
            when X"2" =>
            segments <= "10100100";
            when X"3" =>
            segments <= "10110000";
            when X"4" =>
            segments <= "10011001";
            when X"5" =>
            segments <= "10010010";
            when X"6" =>
            segments <= "10000010";
            when X"7" =>
            segments <= "11111000";
            when X"8" =>
            segments <= "10000000";
            when X"9" =>
            segments <= "10100000";
            when X"A" =>
            segments <= "10001000";
            when X"b" =>
            segments <= "10000011";
            when X"C" =>
            segments <= "11000110";
            when X"d" =>
            segments <= "10100001";
            when X"E" =>
            segments <= "10000110";
            when X"F" =>
            segments <= "10001110";
            when others =>
            segments <= "11111111";
        end case;
    end process;


end Behavioral;

9. Stavové automaty

fsm_moore.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity fsm_moore is
    port(
        clk   : in  std_logic;
        rst   : in  std_logic;
        seq   : in  std_logic;
        found : out std_logic
    );
end fsm_moore;

architecture Behavioral of fsm_moore is

    type fsm_type is (StateStart, S0, S00, S001, S0011);
    signal current_state, next_state : fsm_type;
begin

    -- fsm memory
    mem : process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                current_state <= StateStart;
            else
                current_state <= next_state;
            end if;
        end if;
    end process;

    -- fsm transfer and output function are combinatorial logic
    transfer : process(current_state, seq)
    begin
        -- default state
        next_state <= current_state;
        -- default output
        found      <= '0';
--        case current_state is
--            when StateStart =>
--                -- assign outputs
--                found <= '0';
--                -- transfer function
--                if seq = '1' then
--                    next_state <= StateFound;
--                end if;
--            when StateFound =>
--                found <= '1';
--                if seq = '0' then
--                    next_state <= StateStart;
--                end if;

--            when others =>
--                -- graveyard | eden
--                next_state <= StateStart;
--        end case
        case current_state is
            when StateStart =>
                if seq = '0' then
                    next_state <= S0;
                else
                    next_state <= StateStart;
                end if;
            when S0 =>
                if seq = '0' then
                    next_state <= S00;
                else
                    next_state <= StateStart;
                end if;
            when S00 =>
                if seq = '1' then
                    next_state <= S001;
                else
                    next_state <= S00;
                end if;
            when S001 =>
                if seq = '1' then
                    next_state <= S0011;
                else
                    next_state <= S0;
                end if;
            when S0011 =>
                found <= '1';
                if seq = '0' then
                    next_state <= S0;
                else
                    next_state <= StateStart;
                end if;
            when others =>
                next_state <= StateStart;
        end case;

    end process;

end Behavioral;

fsm_mealy.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity fsm_mealy is
    port(
        clk   : in  std_logic;
        rst   : in  std_logic;
        seq   : in  std_logic;
        found : out std_logic
    );
end fsm_mealy;

architecture Behavioral of fsm_mealy is

    type fsm_type is (StateStart, S0, S00, S001);
    signal current_state, next_state : fsm_type;
begin

    -- fsm memory
    mem : process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                current_state <= StateStart;
            else
                current_state <= next_state;
            end if;
        end if;
    end process;

    -- fsm transfer and output function are combinatorial logic
    transfer : process(current_state, seq)
    begin
        -- default state
--        case current_state is
--            when StateStart =>
--                -- assign outputs
--                -- transfer function
--                if seq = '1' then
--                    next_state <= StateFound;
--                    found      <= '1';
--                else
--                    found <= '0';
--                end if;
--            when StateFound =>
--                if seq = '0' then
--                    next_state <= StateStart;
--                    found      <= '0';
--                else
--                    found <= '1';
--                end if;
--            when others =>
--                -- graveyard | eden
--                next_state <= StateStart;
--        end case;
        next_state <= current_state;
        found <= '0';
        case current_state is
            when StateStart =>
                if seq = '0' then
                    next_state <= S0;
                else
                    next_state <= StateStart;
                end if;
            when S0 =>
                if seq = '0' then
                    next_state <= S00;
                else
                    next_state <= StateStart;
                end if;
            when S00 =>
                if seq = '1' then
                    next_state <= S001;
                else
                    next_state <= S00;
                end if;
            when S001 =>
                if seq = '1' then
                    found <= '1';
                    next_state <= StateStart;
                else
                    next_state <= S0;
                end if;
            when others =>
                next_state <= StateStart;
        end case;
    end process;

end Behavioral;

fsm_compare.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity fsm_compare is
end fsm_compare;

architecture Behavioral of fsm_compare is

    constant CLK_P : time := 10 ns;

    signal clk : std_logic := '0';
    signal rst : std_logic := '1';
    signal seq : std_logic := '0';

    signal moore_found, mealy_found : std_logic;

begin

    clk <= not clk after CLK_P / 2;

    MOORE : entity work.fsm_moore
        port map(
            clk   => clk,
            rst   => rst,
            seq   => seq,
            found => moore_found
        );

    MEALY : entity work.fsm_mealy
        port map(
            clk   => clk,
            rst   => rst,
            seq   => seq,
            found => mealy_found
        );

    tb : process
    begin
        -- insert your stimulus here

        rst <= '1';
        wait for CLK_P;
        rst <= '0';

        -- spatna testovaci sekvence (napr. 1010)
        -- seq <= '1'; wait for CLK_P;
        -- seq <= '0'; wait for CLK_P;
        -- seq <= '1'; wait for CLK_P;
        -- seq <= '0'; wait for CLK_P;

        -- spravna sekvence 0011
        seq <= '0'; wait for CLK_P;
        seq <= '0'; wait for CLK_P;
        seq <= '1'; wait for CLK_P;
        seq <= '1'; wait for CLK_P;

        wait;
    end process;

end Behavioral;