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

8. Paměti a aritmetické obvody

9. Zákaznické obvody

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

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

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