Лекции
Практические
Тесты
Лабораторные
Доп. материалы
Заголовок Цифровые автоматы
Автор Авдеев Н.А.
Нижний колонтитул ПЦУСБ/Лекция 4
Дополнительный нижний колонтитул Авдеев Н.А., 18:44, 25 марта 2014
Слайд: Провести анализ схемы (1)
Слайд: Провести анализ схемы (2)
Слайд: Автомат Мили
Следующее состояние = F (текущее состояние, вход)
Выход = G (текущее состояние, вход)
Слайд: Автомат Мура
Следующее состояние = F (текущее состояние, вход)
Выход = G (текущее состояние)
Слайд: Литература по построению автоматов
Потемкин И.С. Функциональные узлы цифровой автоматики. – 1988, 320 с.
Слайд: Граф состояний и переходов
[svg]
Кодирование выходов
Состояние выхода
Значение y[1:0]
y1
00
y2
10
y3
11
Кодирование состояний
Состояние
Код
Q1
0001
Q2
0010
Q3
0100
Q4
1000
Слайд: Выбор состояний для выходов и кодирование состояний
Слайд: Таблица переходов (таблица истинности логики переходов)
таблица переходов представляет собой альтернативную запись исходного графа
Текущее состояние state
Входы автомата
Следующее состояние next_state
Код
Имя
x[2]
x[1]
Код
Имя
"0001"
Q1
–
'1'
"0010"
Q2
"0001"
Q1
–
'0'
"0001"
Q1
"0010"
Q2
'1'
'0'
"0100"
Q3
"0010"
Q2
–
'1'
"1000"
Q4
"0010"
Q2
–
'0'
"0010"
Q2
"1000"
Q4
–
'1'
"0001"
Q1
"1000"
Q4
–
'0'
"1000"
Q4
"0100"
Q3
–
–
"0100"
Q3
[svg]
Обозначения в таблице:
знак '–' - значение лог. '0' либо '1'
Слайд: Таблица истинности выходной логики
Состояние 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 .
Примеры
case SEL is
when "01" => Z <= A;
when "10" => Z <= B;
when others => Z <= 'X';
end case ;
case INT_A is
when 0 => Z <= A;
when 1 to 3 => Z <= B;
when 4 | 6 | 8 => Z <= C;
when others => Z <= 'X';
end case ;
Примеры ошибок
перекрытие диапазонов
case INT_A is
when 0 => Z <= A;
when 1 to 3 => Z <= B;
when 2 | 6 | 8 => Z <= C; -- illegal
when others => Z <= 'X';
end case ;
Диапазон для вектора задавать нельзя
signal VEC : unsigned ( 2 downto 0 ) ;
....
case VEC is
when "000" to "010"
=> Z <= A; -- illegal
when "111" => Z <= B;
when others => Z <= 'X';
end case ;
Слайд: Перечислимый тип (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 секунды
Слайд: Алгоритм
[svg]
Слайд: Таблица переходов :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)"
если пароль неправильный - перейти в "Начальное состояние"
Режим смены пароля: ввод старого пароля (0-2)
Нажата кнопка Esc
Начальное состояние
Слайд: Таблица переходов (2)
Текущее состояние
Событие (входы)
Следующее состояние
Режим ввода пароля (для доступа) (1)
Ввод второй цифры
Режим ввода пароля (для доступа) (2)
Режим ввода пароля (для доступа) (2)
Ввод третьей цифры
Переход в состояние:
включение "доступ открыт", если пароль правильный
включение сигнала "Доступ закрыт", если пароль не правильный
Режим ввода пароля (для доступа) (1 или 2)
Прошло 5 с
Начальное состояние
доступ открыт
Прошло 3 с
Начальное состояние
Доступ закрыт
Прошло 0.5 с
Начальное состояние
Слайд: Тоже самое в виде графа
[svg]
Слайд: Схема обработки нажатия клавиши
Рисунок - Схема обработки нажатия кнопки 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" ;
Слайд: Граф переходов
[svg]
Слайд: Режимы работы счетчика
[svg]
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)
Слайд: Режимы работы регистра ввода
[svg]
Слайд: Режимы работы регистра ввода (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;
Слайд: NEW