
4 семестр / ППЭВС. Курсовая работа (пример)
.pdfФедеральное агентство связи
Федеральное государственное образовательное бюджетное учреждение высшего профессионального образования «Санкт-Петербургский государственный университет телекоммуникаций
им. проф. М. А. Бонч-Бруевича»
ПРОЕКТИРОВАНИЕ КОНЕЧНОГО АВТОМАТА С РЕАЛИЗАЦИЕЙ В ПЛИС
Курсовая работа по дисциплине «Программное проектирование элементов
вычислительных систем»
Вариант №7 «Автомат для прохода в метро»
Студент: Коваленко Леонид Александрович Курс 2 Группа ИКПИ-81 Преподаватель: Неелова Ольга Леонидовна
Санкт-Петербург
2020
ОГЛАВЛЕНИЕ |
|
ВВЕДЕНИЕ .............................................................................................................................. |
3 |
ЗАДАНИЕ НА КУРСОВОЕ ПРОЕКТИРОВАНИЕ............................................................. |
4 |
Общее задание на курсовое проектирование ................................................................. |
4 |
Вариант задания на курсовое проектирование .............................................................. |
4 |
Диаграмма состояний ....................................................................................................... |
5 |
Работа устройства ............................................................................................................. |
5 |
Код программы .................................................................................................................. |
6 |
СПИСОК ЛИТЕРАТУРЫ..................................................................................................... |
10 |
2
ВВЕДЕНИЕ Конечный автомат – модель вычислительного устройства с фиксированным и
конечным объемом памяти, которое читает и обрабатывает цепочку входных символов, принадлежащих некоторому конечному множеству. Конечные автоматы различают в зависимости от того, какой результат они дают на выходе.
Абстрактный автомат является математической моделью дискретного устройства и описывается шестикомпонентным набором:
= ( , , , , , _)
— множество состояний.
— множество входных сигналов.
— множество выходных сигналов.
— функция переходов.
— функция выходов.
_ — начальное состояние.
Автомат Мили (автомат первого рода) — конечный автомат, выходная последовательность которого зависит от состояния автомата и входных сигналов.
{( + 1) = (( ), ( )) ( ) = ( ( ), ( ))
( ) — текущее состояние, ( + 1) — следующее состояние,
— функция переходов, ( ) — входной сигнал текущего состояния,— функция выходов, ( ) — выходной сигнал текущего состояния.
Автомат Мура (автомат второго рода) — конечный автомат, выходная последовательность которого зависит только от состояния автомата, и не зависит напрямую от входных сигналов.
{( + 1) = (( ), ( )) ( ) = ( ( ))
( ) — текущее состояние, ( + 1) — следующее состояние,
— функция переходов, ( ) — входной сигнал текущего состояния,— функция выходов, ( ) — выходной сигнал текущего состояния.
Причем справедлива эквивалентность автоматов Мили и Мура: для каждого автомата Мили может быть построен эквивалентный ему автомат Мура, и обратно — для каждого автомата Мура может быть построен эквивалентный ему автомат Мили.
Автоматы Мили и Мура широко применяются при проектировании цифровых устройств на основе программируемых логических интегральных схем (ПЛИС).
Основное преимущество использования автомата Мили заключается в возможности реакции автомата в течение текущего такта, что обусловлено зависимостью текущей выходной комбинации от текущей входной комбинации.
Наличие минимальной выходной задержки, связанной с переключением выходного регистра, отсутствие нестабильности переходного процесса на выходе автомата, отсутствие сквозного распространения сигнала через комбинационную схему от входа до выхода автомата, простота описания на языках описания аппаратуры HDL делает автомат Мура практически незаменимым.
3
ЗАДАНИЕ НА КУРСОВОЕ ПРОЕКТИРОВАНИЕ
Общее задание на курсовое проектирование
Необходимо синтезировать конечный автомат с произвольной сменой состояний, каждое из которых отражает некоторое событие. Возможность перехода из одного состояния в другое зависит от сигнала x, который формируется с помощью счетчика тактов. В некоторых заданиях также предусматривается формирование дополнительного управления от внешних источников.
В синтез входит:
1.Построение временной диаграммы работы счетчика тактов с указанием интервалов времени формирования управляющего сигнала x;
2.Программа на Verilog HDL для реализации автомата на макете в FPGA CycloneV;
3.Диаграмма состояний автомата.
Таблица переходов отражает ход смены состояний с учетом времени удержания предшествующего состояния в тактах.
Таблица состояний отражает событие, соответствующее полученному состоянию, и отображение состояния на выходной шине. Состояние выходной шины при реализации выводится на сегментные индикаторы.
Вариант задания на курсовое проектирование
Выбранный вариант: «Автомат для прохода в метро». Состояния автомата:
INITIAL_STATE ( 0) — начальное состояние.
CARD_WAITING_STATE ( 1) — состояние ожидания карты. Индикация «____». Приложенная карта включает счетчик тактов. Сигнал, имитирующий
приложение карты, получается с тумблера 1. Через 2 такта автомат переходит в 2 — состояние чтения карты.
CARD_READING_STATE ( 2) — состояние чтения карты. Индикация «□□□□». Время удержания 2 такта. Определяется корректность кода: биты младшей части должны быть противоположны битам старшей. Определяется достаточность денежных средств на карте путем сравнения текущего баланса и стоимости прохода (45 рублей). Если карта не приложена или код неверный, или средств недостаточно, то автомат переходит в состояние 5, иначе в 3.
CARD_DISPLAY_STATE ( 3) — состояние отображения информации о карте. Автомат выводит в течение 3 тактов новый баланс карты на индикаторах. После этого переходит в состояние 4.
ENTRY_PERMIT_STATE ( 4) — состояние разрешения входа. Выводит новый баланс карты на индикаторах. Проход разрешен. После этого переходит к состоянию 1.
CARD_READING_ERROR_STATE ( 5) — состояние отображения информации об ошибке: «EEEE».
4

Диаграмма состояний
На рисунке 1 представлена диаграмма состояний конечного автомата.
Рисунок 1. Диаграмма состояний
Работа устройства
Посмотрим на следующий рисунок.
Рисунок 2. Пример работы устройства (тестбенч-файл)
Параметры:
T — период синхроимпульса.
CODE_BITS — количество битов в коде (должно быть кратно 2).
MONEY_BITS — количество битов для описания денег (14 битов, но предполагается, что максимально возможное количество денег на счету: 10000 рублей; копейки не учитываются).
Источники сигнала:
clk — синхроимпульс.
ena — разрешение счета cnt при 1.
res — синхронный сброс счетчика cnt при 1.
reset — асинхронный сброс счетчика cnt при 0.
isCardAttached ( 1) — приложена ли карта к устройству считывания.
code — код карты. Код верный, если биты старшей части противоположны битам младшей (в данном примере 000 противоположны 111).
permission — разрешение прохода.
indicators — информационные индикаторы (4 шт.).
currentBalance — текущий баланс.
state — текущее состояние конечного автомата.
cnt — счетчик.
price — стоимость одной поездки (45 рублей).
5

Последовательный вывод на индикаторах:
1.Z-состояние.
2.'____' (состояние ожидания; b1110111).
3.'□□□□' (состояние чтения; b0011100).
4.'EEEE' (состояние ошибки, мало средств; b0000110).
5.'____' (состояние ожидания; b1110111).
6.'□□□□' (состояние чтения; b0011100).
7.'9954' (состояние отображение информации о новом балансе карты: вместо 9954 может быть и другое число; в данном случае от текущего баланса 9999 рублей отнимается стоимость прохода 45 рублей).
8.'____' (состояние ожидания; b1110111).
Код программы
Таблица 1. Файл кодера
|
Вспомогательный кодер: MetroCoder.v |
module MetroCoder |
|
(input wire [3:0] |
in4, |
output reg [6:0] out7); |
|
always @* |
|
case (in4) |
|
4'b0000: out7 |
= 7'b1000000; // '0' |
4'b0001: out7 |
= 7'b1111001; // '1' |
4'b0010: out7 |
= 7'b0100100; // '2' |
4'b0011: out7 |
= 7'b0110000; // '3' |
4'b0100: out7 |
= 7'b0011001; // '4' |
4'b0101: out7 |
= 7'b0010010; // '5' |
4'b0110: out7 |
= 7'b0000010; // '6' |
4'b0111: out7 |
= 7'b1111000; // '7' |
4'b1000: out7 |
= 7'b0000000; // '8' |
4'b1001: out7 |
= 7'b0010000; // '9' |
4'b1010: out7 |
= 7'b1110111; // '_' |
4'b1011: out7 |
= 7'b0011100; // '□' (wait) |
4'b1100: out7 |
= 7'b0000110; // 'E' (error) |
4'b1101: out7 |
= 7'b1110111; // '_' |
4'b1110: out7 |
= 7'b1110111; // '_' |
4'b1111: out7 |
= 7'b1110111; // '_' |
endcase |
|
endmodule |
|
|
|
|
Таблица 2. Файл устройства |
|
|
|
Файл устройства: MetroFSM.v |
module MetroFSM |
|
//Параметр CODE_BITS означает количество бит для описания кода
//Параметр MONEY_BITS означает количество бит для описания денег
#(parameter CODE_BITS = 6, MONEY_BITS = 14)
//clk - тактовый сигнал
//ena - разрешение счета
//res - синхронный сброс
//reset - асинхронный сброс
//code - код для проверки
//indicators - индикаторы
(input wire clk, ena, res, reset, input wire isCardAttached,
input wire [MONEY_BITS-1:0] currentBalance, input wire [CODE_BITS-1:0] code,
output reg permission,
output wire [6:0] indicators [3:0]);
6

// Состояния |
|
|
parameter |
INITIAL_STATE = 0; |
|
parameter |
CARD_WAITING_STATE = |
1; |
parameter |
CARD_READING_STATE = |
2; |
parameter |
CARD_DISPLAY_STATE = |
3; |
parameter |
ENTRY_PERMIT_STATE = |
4; |
parameter |
CARD_READING_ERROR_STATE = 5; |
|
// Индикаторы |
|
|
reg [3:0] |
in4 [3:0]; |
|
MetroCoder cdr1 (.in4(in4[0]), |
.out7(indicators[0])); |
|
MetroCoder cdr2 (.in4(in4[1]), |
.out7(indicators[1])); |
|
MetroCoder cdr3 (.in4(in4[2]), |
.out7(indicators[2])); |
|
MetroCoder cdr4 (.in4(in4[3]), |
.out7(indicators[3])); |
//Состояние, счет, доп. переменные и стоимость проезда reg [2:0] state = INITIAL_STATE;
reg [3:0] cnt = 0; reg s;
reg [CODE_BITS-2:0] i, endi = CODE_BITS >> 1;
reg [MONEY_BITS-1:0] price = 6'b101101, newBalance;
//Управление асинхронным сбросом
always@ (posedge clk or negedge reset) |
|
||
if (!reset) |
begin |
|
|
state <= INITIAL_STATE; |
|
||
cnt <= 4'd0; |
|
|
|
end |
|
|
|
// Логика смен состояний |
|
|
|
always@ (posedge clk or posedge reset) |
|
||
if (res) begin |
|
|
|
state <= INITIAL_STATE; |
|
||
cnt <= 4'd0; |
|
|
|
end |
|
|
|
else case (state) |
|
|
|
INITIAL_STATE: begin |
|
||
|
// Переход к |
состоянию ожидания |
|
|
in4[0] = 4'b1010; // |
'_' |
|
|
in4[1] = 4'b1010; // |
'_' |
|
|
in4[2] = 4'b1010; // |
'_' |
|
|
in4[3] = 4'b1010; // '_' |
|
|
|
permission = |
1'b0; |
|
|
state <= CARD_WAITING_STATE; |
||
end |
|
|
|
CARD_WAITING_STATE: |
|
||
|
// Переход к |
чтению, если 2 такта прошло |
|
|
if (cnt == 4'd2) begin |
|
|
|
in4[0] = |
4'b1011; // |
'□' |
|
in4[1] = |
4'b1011; // |
'□' |
|
in4[2] = |
4'b1011; // |
'□' |
|
in4[3] = |
4'b1011; // '□' |
|
|
state <= |
CARD_READING_STATE; |
|
|
end |
|
|
CARD_READING_STATE: |
|
||
|
// Если карта не приложена, то переход к отображению ошибки |
||
|
if (!isCardAttached) begin |
||
|
in4[0] = |
4'b1100; // |
'E' |
|
in4[1] = |
4'b1100; // |
'E' |
|
in4[2] = |
4'b1100; // |
'E' |
|
in4[3] = |
4'b1100; // 'E' |
|
|
state <= |
CARD_READING_ERROR_STATE; |
|
|
end |
|
|
|
// Переход к |
проверке, если 2 такта прошло |
|
|
else if (cnt |
== 4'd4) begin |
//Проверка кода и баланса
//Проверка кода: код верный, если старшие биты кода
противоположны младшим битам
// Т. е. если биты n, ..., n/2 противоположны n/2-1, ..., 0 s = 1;
7

for (i = 0; i < endi; i = i + 1'b1)
s= s & (code[i] ^ code[i + endi]);
//Проверка баланса: если меньше, то выход с ошибкой if (currentBalance < price || !s) begin
in4[0] = 4'b1100; // |
'E' |
in4[1] = 4'b1100; // |
'E' |
in4[2] = 4'b1100; // |
'E' |
in4[3] = 4'b1100; // 'E' |
|
state <= CARD_READING_ERROR_STATE; |
|
end |
|
else begin |
|
// Перевод числа из двоичной в десятичную для индикаторов |
|
newBalance = currentBalance - price; |
|
i = 0; |
|
while (newBalance >= 1000) begin |
|
newBalance = newBalance - 1000; |
|
i = i + 1; |
|
end |
|
in4[3] = i; |
|
i = 0; |
|
while (newBalance >= 100) begin |
|
newBalance = newBalance - 100; |
|
i = i + 1; |
|
end |
|
in4[2] = i; i = 0;
while (newBalance >= 10) begin newBalance = newBalance - 10; i = i + 1;
end
in4[1] = i;
in4[0] = newBalance;
state <= CARD_DISPLAY_STATE;
end
end
CARD_DISPLAY_STATE:
// Переход к разрешению входа, если 3 такта прошло if (cnt == 4'd7) begin
permission <= 1'b1;
state <= ENTRY_PERMIT_STATE;
end |
|
|
|
ENTRY_PERMIT_STATE: begin |
|
||
in4[0] |
= |
4'b1010; // |
'_' |
in4[1] |
= |
4'b1010; // |
'_' |
in4[2] |
= |
4'b1010; // |
'_' |
in4[3] |
= |
4'b1010; // '_' |
|
permission = 1'b0; |
|
||
state <= |
CARD_WAITING_STATE; |
||
end |
|
|
|
CARD_READING_ERROR_STATE: begin |
|||
in4[0] |
= |
4'b1010; // |
'_' |
in4[1] |
= |
4'b1010; // |
'_' |
in4[2] |
= |
4'b1010; // |
'_' |
in4[3] |
= |
4'b1010; // '_' |
|
state <= |
CARD_WAITING_STATE; |
||
end |
|
|
|
endcase |
|
|
|
// Логика действий внутри состояний |
|
||
always@ (posedge clk) |
|
|
|
if (res) begin |
|
|
|
state <= INITIAL_STATE; |
|
||
cnt <= 4'd0; |
|
|
|
end |
|
|
|
else if (ena) case |
(state) |
|
|
INITIAL_STATE: |
begin |
|
|
cnt <= |
4'd0; |
|
8

end
CARD_WAITING_STATE: begin
cnt <= (isCardAttached ? cnt + 4'd1 : 4'd0);
end
CARD_READING_STATE: begin cnt <= cnt + 4'd1;
end
CARD_DISPLAY_STATE: begin cnt <= cnt + 4'd1;
end
ENTRY_PERMIT_STATE: begin cnt <= 4'd0;
end
CARD_READING_ERROR_STATE: begin cnt <= 4'd0;
end endcase
endmodule
Таблица 3. Тестбенч-файл
Тестбенч: MetroFSM_TB.v
`timescale 1ns/10ps module MetroFSM_TB;
localparam T = 20, CODE_BITS = 6, MONEY_BITS = 14; reg clk, ena, res = 1'b0, reset, isCardAttached; reg [CODE_BITS-1:0] code;
wire permission;
wire [6:0] indicators [3:0];
reg [MONEY_BITS-1:0] currentBalance = 0;
MetroFSM machine(.clk(clk), .ena(ena), .res(res), .reset(reset),
.isCardAttached(isCardAttached), .currentBalance(currentBalance), .code(code),
.permission(permission), .indicators(indicators)); always
begin
clk = 1'b0; #(T / 2); clk = 1'b1; #(T / 2);
end always begin
ena = 1'b0; #(T / 2); ena = 1'b1; #(T / 2);
end initial begin
reset = 1'b0; #(T / 4); reset = 1'b1; isCardAttached = 1'b1;
end initial begin
code = 6'b000111; isCardAttached = 1'b0; currentBalance = 0; repeat(5) @(negedge clk); isCardAttached = 1'b0; @(negedge clk); isCardAttached = 1'b1;
currentBalance = 14'b10011100001111; repeat(10) @(negedge clk);
res = 1'b1;
repeat(2) @(negedge clk); $stop;
end endmodule
9
СПИСОК ЛИТЕРАТУРЫ
1.Неелова О. Л. Лекции по дисциплине «Программное проектирование элементов вычислительных систем».
2.Автоматы Мили и Мура [Электронный ресурс]. – Режим доступа: https://neerc.ifmo.ru/wiki/index.php?title=Автоматы_Мура_и_Мили, свободный –
(29.05.2020).
3.Угрюмов Е. П. Цифровая схемотехника: учеб. пособие для вузов. — 3-е изд.,
перераб. и доп. — СПб.: БХВ-Петербург, 2010. — 816 с.: ил.
10