Čí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:
- Číselné soustavy a kódy: Binární, hexadecimální soustava, doplňkový kód, BCD kód a Grayův kód.
- Booleova algebra: Logické operace (AND, OR, NOT, NAND, NOR, XOR), minimalizace logických funkcí pomocí Karnaughových map.
- Kombinační logické obvody: Kodéry, dekodéry, multiplexory, demultiplexory, sčítačky a komparátory.
- Sekvenční logické obvody: Klopné obvody (RS, D, JK, T), registry, čítače a synchronní automaty.
- 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;