ПЦУСБ/Лекция 4
Материал из Wiki
< ПЦУСБ
- Заголовок
- Цифровые автоматы
- Автор
- Авдеев Н.А.
- Нижний колонтитул
- ПЦУСБ/Лекция 4
- Дополнительный нижний колонтитул
- Авдеев Н.А., 18:44, 25 марта 2014
Слайд: Провести анализ схемы (1)
Слайд: Провести анализ схемы (2)
Слайд: Абстра́ктный автома́т
- Абстра́ктный автома́т (в теории алгоритмов) — математическая абстракция, модель дискретного устройства, имеющего один вход, один выход и в каждый момент времени находящегося в одном состоянии из множества возможных. На вход этому устройству поступают символы одного алфавита, на выходе оно выдаёт символы (в общем случае) другого алфавита.
- Формально абстрактный автомат определяется как пятерка
- где
- S — конечное множество состояний автомата,
- X, Y — конечные входной и выходной алфавиты соответственно, из которых формируются строки, считываемые и выдаваемые автоматом,
- — функция переходов,
- — функция выходов.
Слайд: Автомат Мили
- Следующее состояние = 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; |
library ieee; use ieee.std_logic_1164.all; 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;