Проектирование цифровых систем на языках описания аппаратуры/Лекция 9
- Заголовок
- Описание конечных автоматов и схем с памятью
- Автор
- Ланкевич Ю.Ю.
- Нижний колонтитул
- Проектирование цифровых систем на языках описания аппаратуры/Лекция 9
- Дополнительный нижний колонтитул
- Ланкевич Ю.Ю., 01:15, 12 октября 2020
Слайд:Определение конечного автомата
- Абстра́ктный автома́т (в теории алгоритмов) — математическая абстракция, модель дискретного устройства, имеющего один вход, один выход и в каждый момент времени находящегося в одном состоянии из множества возможных. На вход этому устройству поступают символы одного алфавита, на выходе оно выдаёт символы (в общем случае) другого алфавита.
Ограничение числа состояний абстрактного автомата определило такое понятие как конечный автомат. Конечный автомат K определяется как набор
- A = { a1 ,..., aQ } – множество (алфавит) состояний (имеются в виду внутренние состояния автомата);
- Z = { z1 ,..., zN } – множество входных сигналов (входной алфавит);
- W = { w1 ,..., wM } – множество выходных сигналов (выходной алфавит);
- δ – функция переходов, определяющая состояние автомата в момент времени t+1 в зависимости от состояния автомата и входного сигнала в момент времени t, иначе говоря,
- am – состояние автомата в момент времени t;
- z – входной сигнал в момент времени t;
- as – состояние автомата в момент времени t+1;
- λ – функция выходов.
Слайд:Автомат Мили и автомат Мура
Если функция λ по состоянию автомата aq и входному сигналу zn определяет значение выходного сигнала wm
то конечный автомат называется автоматом Мили , если же
то конечный автомат называется автоматом Мура;
- a1 – начальное состояние автомата в момент времени t =0, a1∈A.
Слайд:Автомат Мили
- Следующее состояние = F (текущее состояние, вход)
- Выход = G (текущее состояние, вход)
Слайд:Автомат Мура
- Следующее состояние = F (текущее состояние, вход)
- Выход = G (текущее состояние)
Слайд: Литература по построению автоматов
- Потемкин И.С. Функциональные узлы цифровой автоматики. – 1988, 320 с.
- Д. Уэйкерли Пректирование цифровых устройств. В 2-х томах / Том 2 — М., 2002 Т. 2. — 536 с. – глава 7 посвящена проектированию автоматов.
- Бибило П.Н. Основы языка VHDL: Учебное пособие. – М.: Книжный дом «ЛИБРОКОМ», 2012. – 328 с. – Глава 4.3 посвящена описанию автоматов на VHDL
Слайд: Граф состояний и переходов
|
|
Слайд: Выбор состояний для выходов и кодирование состояний
- Для хранения значения текущего состояния автомата используется 4-х разрядный регистр со сбросом в "0001" (код состояния Q1), который реализуется с помощью 4-х D-триггеров с асинхронными сбросом и установкой.
Слайд: Таблица переходов (таблица истинности логики переходов F)
- таблица переходов представляет собой альтернативную запись исходного графа
|
|
Обозначения в таблице:
- знак '–' - значение лог. '0' либо '1'
Слайд: Таблица истинности выходной логики G
Состояние State[3:0] |
Выход y[1:0] | ||
---|---|---|---|
Имя | Код | Имя | Код |
Q1 | "0001" | y1 | "00" |
Q2 | "0010" | y2 | "10" |
Q3 | "0100" | y1 | "00" |
Q4 | "1000" | y3 | "11" |
Слайд: VHDL-модель автомата
Вариант 1 | Вариант 2 | Вариант 3 |
---|---|---|
library ieee; use ieee.std_logic_1164.all; entity automat is port ( x : in std_logic_vector(2 downto 1); rst : in std_logic; clk : in std_logic; y : out std_logic_vector(1 downto 0)); end automat; architecture beh of automat is signal state : std_logic_vector(3 downto 0); signal next_state : std_logic_vector(3 downto 0); begin -- beh -- Задание логики переходов (F) next_state <= "0010" when state="0001" and x(1)='1' else "0001" when state="0001" else "0100" when state="0010" and x(2 downto 1) = "10" else "1000" when state="0010" and x(1)='1' else "0010" when state="0010" else "0001" when state="1000" and x(1)='1' else "1000" when state="1000" else "0100" when state="0100" else "0000"; -- Задание выходной логики (G) y <= "00" when state="0001" else "10" when state="0010" else "00" when state="0100" else "11" when state="1000" else "00"; -- регистр, хранящий текущее состояние p1: process (clk, rst) begin -- process p1 if rst = '1' then state <= "0001"; elsif clk'event and clk = '1' then state <= next_state; end if; end process p1; end beh; |
architecture beh2 of automat is type state_type is (Q1, Q2, Q3, Q4); signal state : state_type; signal next_state : state_type; begin -- beh c1: process (state, x) is begin -- process c1 case state is when Q1 => y <= "00"; if x(1)='1' then next_state <= Q2; else next_state <= Q1; end if; when Q2 => y <= "10"; if x = "10" then next_state <= Q3; elsif x(1) = '1' then next_state <= Q4; else next_state <= Q2; end if; when Q3 => y <= "00"; next_state <= Q3; when Q4 => y <= "11"; if x(1) = '1' then next_state <= Q1; else next_state <= Q4; end if; when others => null; end case; end process c1; -- регистр, хранящий текущее состояние p1: process (clk, rst) begin -- process p1 if rst = '1' then state <= Q1; elsif clk'event and clk = '1' then state <= next_state; end if; end process p1; end beh2; |
architecture beh3 of automat is type state_type is (Q1, Q2, Q3, Q4); signal state : state_type; begin -- beh p1: process (clk, rst) begin -- process p1 if rst = '1' then state <= Q1; elsif clk'event and clk = '1' then if state = Q1 then if x(1)='1' then state <= Q2; end if; elsif state = Q2 then if x = "10" then state <= Q3; elsif x(1) = '1' then state <= Q4; end if; elsif state = Q3 then elsif state = Q4 then if x(1) = '1' then state <= Q1; end if; else -- защита от сбоя state <= Q1; end if; end if; end process p1; -- Задание выходной логики (G) y <= "00" when state = Q1 else "10" when state = Q2 else "00" when state = Q3 else "11" when state = Q4 else "00"; end beh3; |
Слайд: Последовательный оператор CASE
- Последовательный — значит может использоваться только в process
case Выражение is when Значение => Последовательные операторы when Значение [ | Значение ] => Последовательные операторы end case;
- Значение может быть числом (литералом), простым выражением (например, a + b), диапазоном значений (1 to 10), ключевым словом others.
Слайд: Перечислимый тип (TYPE)
- Перечислимый тип — это такой тип данных, при котором количество всех возможных значений конечно.
- улучшение смысловой читаемости программы;
- более четкий и простой визуальный контроль значений.
- Наиболее часто перечислимый тип используется для обозначения состояний конечных автоматов.
- Перечислимый тип объявляется путем перечисления названий элементов-значений.
- Элементы перечислимого типа должны быть идентификаторами или символами, которые должны быть уникальными в пределах одного типа.
- Повторное использование названий элементов в других перечислимых типах разрешается.
- Объявление перечислимого типа имеет вид:
TYPE имя_типа IS ( название_элемента [, название_элемента] );
- Пример
type State_type IS (stateA, stateB, stateC); signal State : State_type; . . . State <= stateB
- Примеры предопределенных перечислимых типов:
TYPE SEVERITY_LEVEL IS (NOTE, WARNING, ERROR, FAILURE); TYPE BOOLEAN IS (FALSE, TRUE); TYPE BIT IS ('0', '1'); TYPE STD_LOGIC IS ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
- Любой перечислимый тип имеет внутреннюю нумерацию: первый элемент всегда имеет номер 0, второй - номер 1 и т.д. Порядок нумерации соответствует порядку перечисления.
Слайд: VHDL-модель тестбенча
library ieee; use ieee.std_logic_1164.all; entity tb is end tb; architecture beh of tb is component automat port ( x : in std_logic_vector(2 downto 1); rst : in std_logic; clk : in std_logic; y : out std_logic_vector(1 downto 0)); end component; signal x : std_logic_vector(2 downto 1); signal rst : std_logic; signal clk : std_logic := '0'; signal y : std_logic_vector(1 downto 0); begin -- beh automat_1: automat port map ( x => x, rst => rst, clk => clk, y => y); clk <= not clk after 10 ns; rst <= '1', '0' after 30 ns, '1' after 400 ns, '0' after 405 ns; process begin -- process x <= "00"; wait for 55 ns; x <= "01"; wait for 20 ns; x <= "01"; wait for 20 ns; x <= "01"; wait for 20 ns; x <= "01"; wait for 40 ns; x <= "10"; wait for 40 ns; x <= "11"; wait for 40 ns; x <= "10"; wait for 40 ns; x <= "01"; wait; end process; end beh;
Слайд: Временные диаграммы
Слайд: Словесное описание автомата
Панель ввода пароля
- обеспечить возможность задания нового пароля по нажатию специальной кнопки и ввода старого пароля (пароль по умолчанию 000), а затем ввода нового. При неправильном вводе переходит в начальное состояние (ожидание ввода). При правильном старом пароле включить сигнал "доступ открыт", а после ввода нового пароля отключить сигнал "доступ открыт".
- ввод пароля с клавиатуры (3х значное десятичное число от 000 до 999). Предусмотреть кнопку сброса введённого пароля (при неправильнном вводе).
- после ввода 3 цифр система проверяет введённый пароль с внутренним значением:
- если пароли совпадают, то включается светодиод "Доступ открыт" на 3 сек., после чего система переходит в режим ввода пароля
- если пароли не совпадают, то включается звуковой сигнал "Доступ закрыт" на 0.5 сек., после чего система переходит в режим ввода пароля
- если после ввода 1й или 2й цифры, следующая цифра (т.е. 2-я или 3я соответственно) не введены более чем через 5 секунд, то включается звуковой сигнал "Доступ закрыт" на 0.5 секунды
Слайд: Алгоритм
Слайд: Таблица переходов :step
Элементы системы и управляющие сигналы (входы/выходы)
- Входы
- кнопка ввода пароля - сигнал SetPassword
- цифровые кнопки 0-9 - сигналы DigitalKey[8 downto 0]
- кнопка отмены ввода - сигнал Esc
- сигналы (со счетчика) отсчитывающие 0.5, 3, 5 с - Dalay05s, Dalay3s, Dalay5s
- сигнал синхронизации - clk (активный положительный фронт)
- асинхронный сброс - RST
- Выходы
- управление трехразрядным семисегментным индикатором - Digits2[6:0], Digits1[6:0], Digits0[6:0] (реально Digits[6:0] и Index[2:0])
- светодиод "Доступ открыт" - сигнал Open
- Динамик - сигнал Speaker
- Сигнал запуск отсчета паузы - StartCount
Слайд: Таблица переходов
Текущее состояние | Событие (входы) | Следующее состояние |
---|---|---|
Любое | RST = 1 | Начальное состояние (ожидание ввода) |
Начальное состояние | Нажата кнопка ввода пароля | Режим смены пароля: ввод старого пароля |
Начальное состояние | Нажата цифровая кнопка | Режим ввода пароля (для доступа) (1) |
Начальное состояние | Нажата кнопка Esc | Начальное состояние |
Режим смены пароля: ввод старого пароля (0) | Ввод первой цифры | Режим смены пароля: ввод старого пароля (1), отобразить введённую цифру |
Режим смены пароля: ввод старого пароля (0) | Прошло 5 с | Начальное состояние |
Режим смены пароля: ввод старого пароля (1) | Ввод второй цифры | Режим смены пароля: ввод старого пароля (2), отобразить введённую цифру |
Режим смены пароля: ввод старого пароля (1) | Прошло 5 с | Начальное состояние |
Режим смены пароля: ввод старого пароля (2) | Ввод третьей цифры | Режим смены пароля:
|
Режим смены пароля: ввод старого пароля (0-2) | Нажата кнопка Esc | Начальное состояние |
Слайд: Таблица переходов (2)
Текущее состояние | Событие (входы) | Следующее состояние |
---|---|---|
Режим ввода пароля (для доступа) (1) | Ввод второй цифры | Режим ввода пароля (для доступа) (2) |
Режим ввода пароля (для доступа) (2) | Ввод третьей цифры | Переход в состояние:
|
Режим ввода пароля (для доступа) (1 или 2) | Прошло 5 с | Начальное состояние |
доступ открыт | Прошло 3 с | Начальное состояние |
Доступ закрыт | Прошло 0.5 с | Начальное состояние |
Слайд: Тоже самое в виде графа
Слайд: Схема обработки нажатия клавиши
|
---|
Рисунок - Схема обработки нажатия кнопки Esc (Edit) |
EscPress_i1 | EscPress_i0 | EscPress_i |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 0 |
Логическое выражение | ||
EscPress_i <= EscPress_i1 and not EscPress_i0 |
Слайд: Схема обработки нажатия клавиши (VHDL)
signal EscPress_i0 : std_logic; signal EscPress_i1 : std_logic; signal EscPress_i : std_logic; signal EscPress : std_logic; begin -- architecture beh -- обработка нажатия клавиш trig: process (clk, rst) is begin -- process trig if rst = '1' then -- асинхронный сброс EscPress <= '0'; EscPress_i0 <= '0'; EscPress_i1 <= '0'; elsif clk'event and clk = '1' then -- rising clock edge EscPress_i1 <= Esc; EscPress_i0 <= EscPress_i1; EscPress <= EscPress_i; end if; end process trig; EscPress_i <= EscPress_i1 and not EscPress_i0;
Слайд: Блоки обработки нажатия клавиш
|
---|
Рисунок - Блоки обработки нажатия кнопок (Edit) |
Слайд: Блок обработки нажатия цифровых клавиш
|
---|
Рисунок - Блок обработки нажатия цифровых клавиш (Edit) |
Слайд: Блок обработки нажатия цифровых клавиш (VHDL)
InputCodePress <= '0' when KeyCode = "1111" else '1'; p_KeyCode: process (clk, rst) is begin if rst = '1' then KeyCode <= "1111"; elsif clk'event and clk = '1' then -- rising clock edge KeyCode <= KeyCode_i; end if; end process p_KeyCode; KeyCode_i <= "0000" when DigitalKey(0) = '1' else "0001" when DigitalKey(1) = '1' else "0010" when DigitalKey(2) = '1' else "0011" when DigitalKey(3) = '1' else "0100" when DigitalKey(4) = '1' else "0101" when DigitalKey(5) = '1' else "0110" when DigitalKey(6) = '1' else "0111" when DigitalKey(7) = '1' else "1000" when DigitalKey(8) = '1' else "1001" when DigitalKey(9) = '1' else "1111";
Слайд: Граф переходов
Слайд: Режимы работы счетчика
|
signal count : unsigned(12 downto 0); signal Delay05s, Delay3s, Delay5s : boolean; begin -- architecture beh -- описание счетчика для отсчета времени p_count: process (clk, rst) is begin -- process p_count if rst = '1' then count <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge if EscPress = '1' or SetPasswordPress = '1' or DigitalKeyPress = '1' or Delay5s then count <= (others => '0'); else count <= count + 1; end if; end if; end process p_count; Delay05s <= (count = 500); -- отсчет 0.5 с Delay3s <= (count = 3000); -- отсчет 3 с Delay5s <= (count = 5000); -- отсчет 5 с |
---|
- тип boolean (Delay05s)
- тип unsigned (count)
Слайд: Режимы работы регистра ввода
Слайд: Режимы работы регистра ввода (VHDL)
signal KeyCode_i, KeyCode : std_logic_vector(3 downto 0); type STATE_TYPE is ( Start , InputPassword1 , InputPassword2 , InputPasswordCompare , OpenAccess , InputPasswordNotCompared ); signal state, next_state : STATE_TYPE; type WORD_TYPE is array (1 to 3) of std_logic_vector(3 downto 0); signal Password : WORD_TYPE := ("0001", "0010", "0011"); signal InputCode : WORD_TYPE; begin p2: process (clk, rst) is begin if rst = '1' then InputCode <= ("0000", "0000", "0000"); elsif clk'event and clk = '1' then -- rising clock edge if state = Start then if DigitalKeyPress = '1' then InputCode(1) <= KeyCode; end if; elsif state = InputPassword1 then if DigitalKeyPress = '1' then InputCode(2) <= KeyCode; end if; elsif state = InputPassword2 then if DigitalKeyPress = '1' then InputCode(3) <= KeyCode; end if; else InputCode <= ("0000", "0000", "0000"); end if; end if; end process p2;
Слайд: VHDL-модель
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity block1 is port ( SetPassword : in std_logic; DigitalKey : in std_logic_vector(9 downto 0); Esc : in std_logic; clk : in std_logic; -- синхросигнал 25 МГц rst : in std_logic; LedOpen : out std_logic; Speaker : out std_logic); end entity block1; architecture beh2 of block1 is signal count : unsigned(12 downto 0); signal KeyCode_i, KeyCode : std_logic_vector(3 downto 0); type STATE_TYPE is ( Start , InputPassword1 , InputPassword2 , InputPasswordCompare , OpenAccess , InputPasswordNotCompared ); signal state, next_state : STATE_TYPE; type WORD_TYPE is array (1 to 3) of std_logic_vector(3 downto 0); signal Password : WORD_TYPE := ("0001", "0010", "0011"); signal InputCode : WORD_TYPE; signal Delay05s, Delay3s, Delay5s : boolean; signal InputCodePress : std_logic; signal InputCodePress_i0 : std_logic; signal InputCodePress_i1 : std_logic; signal InputCodePress_i : std_logic; signal DigitalKeyPress : std_logic; signal SetPasswordPress_i0 : std_logic; signal SetPasswordPress_i1 : std_logic; signal SetPasswordPress_i : std_logic; signal SetPasswordPress : std_logic; signal EscPress_i0 : std_logic; signal EscPress_i1 : std_logic; signal EscPress_i : std_logic; signal EscPress : std_logic; begin -- architecture beh -- обработка нажатия клавиш trig: process (clk, rst) is begin -- process trig if rst = '1' then -- асинхронный сброс EscPress <= '0'; EscPress_i0 <= '0'; EscPress_i1 <= '0'; SetPasswordPress <= '0'; SetPasswordPress_i0 <= '0'; SetPasswordPress_i1 <= '0'; DigitalKeyPress <= '0'; InputCodePress_i0 <= '0'; InputCodePress_i1 <= '0'; elsif clk'event and clk = '1' then -- rising clock edge InputCodePress_i1 <= InputCodePress; InputCodePress_i0 <= InputCodePress_i1; DigitalKeyPress <= InputCodePress_i; EscPress_i1 <= Esc; EscPress_i0 <= EscPress_i1; EscPress <= EscPress_i; SetPasswordPress_i1 <= SetPassword; SetPasswordPress_i0 <= SetPasswordPress_i1; SetPasswordPress <= SetPasswordPress_i; end if; end process trig; SetPasswordPress_i <= SetPasswordPress_i1 and not SetPasswordPress_i0 ; EscPress_i <= EscPress_i1 and not EscPress_i0; InputCodePress_i <= InputCodePress_i1 and not InputCodePress_i0; -- описание счетчика для отсчета времени p_count: process (clk, rst) is begin -- process p_count if rst = '1' then count <= (others => '0'); elsif clk'event and clk = '1' then -- rising clock edge if EscPress = '1' or SetPasswordPress = '1' or DigitalKeyPress = '1' or Delay5s then count <= (others => '0'); else count <= count + 1; end if; end if; end process p_count; Delay05s <= (count = 500); -- отсчет 0.5 с Delay3s <= (count = 3000); -- отсчет 3 с Delay5s <= (count = 5000); -- отсчет 5 с p_state: process (clk, rst) is begin if rst = '1' then state <= Start; elsif clk'event and clk = '1' then -- rising clock edge state <= next_state; end if; end process p_state; p_next_state: process (state, EscPress, SetPasswordPress, DigitalKeyPress, Delay5s, Delay3s, Delay05s) is begin case state is when Start => if DigitalKeyPress = '1' then next_state <= InputPassword1; else next_state <= Start; end if; when InputPassword1 => if DigitalKeyPress = '1' then next_state <= InputPassword2; elsif EscPress = '1' or Delay5s then next_state <= Start; else next_state <= InputPassword1; end if; when InputPassword2 => if DigitalKeyPress = '1' then next_state <= InputPasswordCompare; elsif EscPress = '1' or Delay5s then next_state <= Start; else next_state <= InputPassword2; end if; when InputPasswordCompare => if InputCode = Password then next_state <= OpenAccess; else next_state <= InputPasswordNotCompared; end if; when OpenAccess => if Delay3s then next_state <= Start; end if; when InputPasswordNotCompared => if Delay05s then next_state <= Start; end if; when others => next_state <= Start; end case; end process p_next_state; LedOpen <= '1' when state = OpenAccess else '0'; Speaker <= '1' when state = InputPasswordNotCompared else '0'; p2: process (clk, rst) is begin if rst = '1' then InputCode <= ("0000", "0000", "0000"); elsif clk'event and clk = '1' then -- rising clock edge if state = Start then if DigitalKeyPress = '1' then InputCode(1) <= KeyCode; end if; elsif state = InputPassword1 then if DigitalKeyPress = '1' then InputCode(2) <= KeyCode; end if; elsif state = InputPassword2 then if DigitalKeyPress = '1' then InputCode(3) <= KeyCode; end if; else InputCode <= ("0000", "0000", "0000"); end if; end if; end process p2; InputCodePress <= '0' when KeyCode = "1111" else '1'; p_KeyCode: process (clk, rst) is begin if rst = '1' then KeyCode <= "1111"; elsif clk'event and clk = '1' then -- rising clock edge KeyCode <= KeyCode_i; end if; end process p_KeyCode; KeyCode_i <= "0000" when DigitalKey(0) = '1' else "0001" when DigitalKey(1) = '1' else "0010" when DigitalKey(2) = '1' else "0011" when DigitalKey(3) = '1' else "0100" when DigitalKey(4) = '1' else "0101" when DigitalKey(5) = '1' else "0110" when DigitalKey(6) = '1' else "0111" when DigitalKey(7) = '1' else "1000" when DigitalKey(8) = '1' else "1001" when DigitalKey(9) = '1' else "1111"; end architecture beh2;
Слайд: VHDL-модель тестбенча
library ieee; use ieee.std_logic_1164.all; ------------------------------------------------------------------------------- entity block1_tb is end entity block1_tb; ------------------------------------------------------------------------------- architecture tb of block1_tb is -- component ports signal SetPassword : std_logic; signal DigitalKey : std_logic_vector(9 downto 0); signal Esc : std_logic; signal rst : std_logic; signal LedOpen : std_logic; signal Speaker : std_logic; signal Clk : std_logic := '1'; begin -- architecture tb -- component instantiation DUT: entity work.block1(beh2) port map ( SetPassword => SetPassword, DigitalKey => DigitalKey, Esc => Esc, clk => clk, rst => rst, LedOpen => LedOpen, Speaker => Speaker); -- clock generation Clk <= not Clk after 5 ns; -- waveform generation WaveGen_Proc: process begin -- insert signal assignments here SetPassword <= '0'; DigitalKey <= (others => '0'); Esc <= '0'; rst <= '1'; wait for 21 ns; rst <= '0'; wait for 10 ns; DigitalKey(1) <= '1'; wait for 50 ns; DigitalKey(1) <= '0'; Esc <= '0'; wait for 50 ns; DigitalKey(2) <= '1'; wait for 50 ns; DigitalKey(2) <= '0'; wait for 50 ns; Esc <= '0'; DigitalKey(3) <= '1'; wait for 50 ns; DigitalKey(3) <= '0'; wait for 10 ns; wait; end process WaveGen_Proc; end architecture tb;
Слайд: Временные диаграммы
Слайд: VHDL-модель (другой вариант описания)
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity block1 is port ( SetPassword : in std_logic; DigitalKey : in std_logic_vector(9 downto 0); Esc : in std_logic; clk : in std_logic; -- синхросигнал 25 МГц rst : in std_logic; LedOpen : out std_logic; Speaker : out std_logic); end entity block1; architecture beh of block1 is signal count : unsigned(12 downto 0); signal KeyCode : std_logic_vector(3 downto 0); -- access denied -- open access type STATE_TYPE is ( Start , InputPassword1 , InputPassword2 , InputPasswordCompare , OpenAccess , InputPasswordNotCompared ); signal state : STATE_TYPE; -- type WORD_TYPE is array (3 downto 0) of std_logic; type WORD_TYPE is array (1 to 3) of std_logic_vector(3 downto 0); -- signal password : array (1 to 3) of WORD_TYPE; signal Password : WORD_TYPE := ("0000", "0000", "0000"); signal InputCode : WORD_TYPE; signal Delay05s, Delay3s, Delay5s : boolean; begin -- architecture beh p1: process (clk, rst) is begin -- process p1 if rst = '1' then count <= (others => '0'); state <= Start; LedOpen <= '0'; Speaker <= '0'; elsif clk'event and clk = '1' then -- rising clock edge count <= count + 1; -- непрерывный отсчет времени if state = Start then LedOpen <= '0'; Speaker <= '0'; if KeyCode /= "1111" then state <= InputPassword1; InputCode(1) <= KeyCode; count <= (others => '0'); -- сброс счетчика end if; elsif state = InputPassword1 then if KeyCode /= "1111" then state <= InputPassword2; InputCode(2) <= KeyCode; count <= (others => '0'); -- сброс счетчика end if; elsif state = InputPassword2 then if KeyCode /= "1111" then state <= InputPasswordCompare; InputCode(3) <= KeyCode; count <= (others => '0'); -- сброс счетчика end if; elsif state = InputPasswordCompare then if Password = InputCode then state <= OpenAccess; LedOpen <= '1'; else state <= InputPasswordNotCompared; Speaker <= '1'; end if; count <= (others => '0'); -- сброс счетчика elsif state = InputPasswordNotCompared then if Delay05s then Speaker <= '0'; state <= Start; end if; elsif state = OpenAccess then if Delay3s then LedOpen <= '0'; state <= Start; end if; else -- сброс в начальное состояние state <= Start; end if; end if; -- сброс в начальное состояние -- если 5 с не были нажаты кнопки -- или нажат Esc if Delay5s or Esc = '1' then state <= Start; end if; end process p1; Delay05s <= (count = 500); -- отсчет 0.5 с Delay3s <= (count = 3000); -- отсчет 3 с Delay5s <= (count = 5000); -- отсчет 5 с KeyCode <= "0000" when DigitalKey(0) = '1' else "0001" when DigitalKey(1) = '1' else "0010" when DigitalKey(2) = '1' else "0011" when DigitalKey(3) = '1' else "0100" when DigitalKey(4) = '1' else "0101" when DigitalKey(5) = '1' else "0110" when DigitalKey(6) = '1' else "0111" when DigitalKey(7) = '1' else "1000" when DigitalKey(8) = '1' else "1001" when DigitalKey(9) = '1' else "1111"; end architecture beh;
Слайд:Пример автомата Мили
Функционирование автомата происходит следующим образом: в дискретные моменты времени t = 0, 1, 2, 3,... на вход устройства поступает входной сигнал – один из элементов множества Z,
а на выходе появляется выходной сигнал – один из элементов множества W, в этот же момент времени t автомат из состояния am переходит в состояние as, в котором он будет находиться в момент времени t+1.
Разработаны различные формы задания конечных автоматов. Например, в таблице задан конечный автомат Мили с четырьмя внутренними состояниями
Входные сигналы | Состояния | |||
---|---|---|---|---|
a1 | a2 | a3 | a4 | |
z1 | a2/w1 | a2/w1 | a1/w2 | a1/w4 |
z2 | a4/w5 | a3/w3 | a4/w4 | a3/w5 |
Алфавит состояний A = {a1, a2, a3, a4}, q = 1,...,4. Входной алфавит Z образуют сигналы z1, z2, т.е. Z = {z1 , z2 }, n = 1,2.
Выходной алфавит W образуют сигналы w1, ..., w5, т.е. W = {w1,w2,w3,w4,w5}, m = 1,...,5. На пересечении строки zn и столбца aq в таблице находится состояние as ,
в которое должен перейти автомат из состояния aq под воздействием сигнала zn.
После косой черты в этой же графе таблицы указывается выходной сигнал, выдаваемый автоматом в состоянии aq при поступлении на его вход сигнала zn.
Иначе говоря, выше представлена таблица задания функций δ , λ, которая называется совмещенной таблицей переходов и выходов.
Автомат может быть задан ориентированным графом, в котором вершинам соответствуют абстрактные внутренние состояния автомата, а дуги соответствуют переходам между состояниями.
Такой граф носит название графа автомата. Для автомата, заданного в таблице, граф автомата имеет следующий вид.

Легко видеть, что совмещенная таблица переходов и выходов автомата и граф автомата являются эквивалентными формами задания поведения конечного автомата Мили.
Слайд:Пример VHDL модели автомата Мили
Следующий VHDL-код реализует поведение конечного автомата, заданного в таблице. Поведение автомата представляется в виде совокупности двух взаимодействующих процессов.
Процесс NS определяет выходной сигнал w и внутренний сигнал NEXT_state, который является входным для процесса REG. Заметим, однако, что в списке чувствительности процесса REG имеется только сигнал clk, который соответствует моментам времени срабатывания автомата.
Для задания состояний автомата в архитектурном теле определяется перечислимый тип t_state. Предполагается, что начальное состояние автомата равно a1.
Начальное состояние явно не указывается, так как при инициализации будет взят элемент нижней границы перечислимого типа – это и будет элемент a1.
Library work; use work.vv_vls.all; entity FSM_A is port ( z : in fsm_in_type; clk : in bit; w : out fsm_out_type); end FSM_A; architecture rtl_a of fsm_a is type T_state is (a1,a2,a3,a4); signal NEXT_state : T_state; signal state : T_state; begin NS : process (state, z) begin case state is when a1 => if (z=z1) then NEXT_state <= a2; w <= w1; elsif (z=z2) then NEXT_state <= a4; w <= w5; end if; when a2 => if (z=z1) then NEXT_state <= a2; w <= w1; elsif (z=z2) then NEXT_state <= a3; w <= w3; end if; when a3 => if (z=z1) then NEXT_state <= a1; w <= w2; elsif (z=z2) then NEXT_state <= a4; w <= w4; end if; when a4 => if (z=z1) then NEXT_state <= a1; w <= w4; elsif (z=z2) then NEXT_state <= a3; w <= w5; end if; end case; end process; REG : process(clk) begin if clk = '1' then state <= NEXT_state; end if; end process; end rtl_a;
Слайд:Пример VHDL модели автомата Мили
Для входных сигналов автомата в пакете vv_vls определяется перечислимый тип
type fsm_in_type is (z1, z2);
для выходных сигналов в том же пакете определяется перечислимый тип
type fsm_out_type is (w1 , w2 ,w3 ,w4 ,w5);package vv_vls is type fsm_in_type is (z1, z2); type fsm_out_type is (w1, w2, w3, w4, w5); end vvv; package body vvv is end vvv;
Многократное изменение синхросигнала clk можно более компактно описать в виде процесса generator. Переменная number задает число тактов. В данном случае число тактов равно 5.
generator : process variable number : integer := 5; begin for i in 1 to number loop clk <= transport '1'; wait for 25 ns; clk <= transport '0'; wait for 25 ns; end loop; end process;
При описании схем с памятью выделяют комбинационную часть автомата и память. Описание поведения выполняют в виде совокупности двух взаимодействующих процессов – процесса NS и детализированного процесса REG. Для рассмотренного примера конечного автомата выделение подсхем показано на рисунке.
