Скачиваний:
2
Добавлен:
23.12.2025
Размер:
396.17 Кб
Скачать

МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

ФАКУЛЬТЕТ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И ПРОГРАММНОЙ ИНЖЕНЕРИИ (ИТПИ)

КАФЕДРА ПРОГРАММНОЙ ИНЖЕНЕРИИ И ВЫЧИСЛИТЕЛЬНОЙ ТЕХНИКИ (ПИ И ВТ)

Дисциплина: «Архитектура распределенных вычислительных систем»

Лабораторная работа №6.

Тема: «Программное проектирование конечного автомата для турникета метро»

Выполнили:

студенты группы ИКПИ-32

Кларк А. Е.

Блинов И. С.

Яковлев М. А.

Приняла:

Неелова О. Л.

Подпись ______________

Санкт-Петербург

2025

Цель работы

Изучение методов программного проектирования конечных автоматов на примере создания управляющего устройства для турникета метрополитена. Определение количества состояний автомата, условий перехода между ними и действий, выполняемых в каждом состоянии для обработки данных карты, проверки баланса и управления доступом.

Необходимо записать программу функционирования конечного автомата, который имитирует работу турникета в метрополитене. Автомат для прохода в метро работает следующим образом: S0 – начальное состояние, затем S1 – ожидание карты с индикацией «__», при приложении карты (тумблер Т1) через переход в S2 – чтение карты с индикацией «__» в течение 2 тактов, баланс определяется положением тумблеров через таблицу перекодировки, затем S3 – индикация остатка баланса после вычета тарифа в течение 3 тактов с переходом в S4 при достаточном балансе или возврат в S1 при недостаточном, S4 – вход разрешен с выходом G (турникет открыт) на 4 такта, после чего возврат в S1.

Рисунок 1. Схема проектируемого устройства

Ход выполнения

Файл coder.v : модуль coder выполняет преобразование 4-битного входного двоичного числа (data) в код для семисегментного индикатора (seg). Дополнен символами для отображения статуса карты.

module coder

(input wire [3:0] data,

output wire[6:0] seg);

reg [6:0]code;

assign seg=code;

always @*

case(data)

4'b0000: code = 7'b1000000; // 0

4'b0001: code = 7'b1111001; // 1

4'b0010: code = 7'b0100100; // 2

4'b0011: code = 7'b0110000; // 3

4'b0100: code = 7'b0011001; // 4

4'b0101: code = 7'b0010010; // 5

4'b0110: code = 7'b0000010; // 6

4'b0111: code = 7'b1111000; // 7

4'b1000: code = 7'b0000000; // 8

4'b1001: code = 7'b0010000; // 9

4'b1010: code = 7'b0111111; // _

4'b1011: code = 7'b1000010; // G

4'b1100: code = 7'b1000111; // L

default: code = 7'b1111111; // выключено

endcase

endmodule

Файл divider.v: модуль divider реализует программируемый делитель частоты. Используется для замедления работы автомата до видимой скорости.

module divider

#(parameter DIVIDER = 2000000)

(

input wire clk_in,

input reset,

output reg clk_out = 0

);

reg [31:0] counter = 0;

always@(posedge clk_in or posedge reset)

begin

if (reset) begin

counter <= 0;

clk_out <= 0;

end else begin

if (counter == DIVIDER - 1)

begin

counter <= 0;

clk_out <= ~clk_out;

end

else

begin

counter <= counter + 1;

end

end

end

endmodule

Файл metro_fsm2.v: модуль metro_fsm реализует конечный автомат, управляющий логикой работы турникета.

module metro_fsm(

input clk,

input reset,

input T1,

input [2:0] balance,

output reg [3:0] seg_data,

output reg [3:0] seg_data1

);

reg [2:0] state;

reg [2:0] cnt;

reg [2:0] current_balance;

parameter INIT = 0, WAIT_CARD = 1, READ_CARD = 2, DISPLAY_BALANCE = 3, ACCESS_GRANTED = 4;

parameter TARIFF = 3;

always @(posedge clk or posedge reset)

begin

if (reset)

state <= INIT;

else begin

case (state)

INIT: state <= WAIT_CARD;

WAIT_CARD: if (T1 && cnt == 2'd0) state <= READ_CARD;

READ_CARD: if (cnt == 2'd1) state <= DISPLAY_BALANCE;

DISPLAY_BALANCE:

if (cnt == 2'd2) begin

if (current_balance >= TARIFF)

state <= ACCESS_GRANTED;

else

state <= WAIT_CARD;

end

ACCESS_GRANTED:

if (cnt == 2'd3) state <= WAIT_CARD;

default: state <= INIT;

endcase

end

end

always @(posedge clk )

begin

case (state)

INIT: begin

cnt <= 2'd0;

seg_data <= 4'b1010;

seg_data1 <= 4'b1111;

current_balance <= 3'b000;

end

WAIT_CARD: begin

seg_data <= 4'b1010;

seg_data1 <= 4'b1111;

end

READ_CARD: begin

if (cnt == 2'd1) begin

cnt <= 2'd0;

current_balance <= balance;

end else begin

cnt <= cnt + 2'd1;

end

seg_data <= 4'b1010;

end

DISPLAY_BALANCE: begin

if (cnt == 2'd2)

cnt <= 2'd0;

else

cnt <= cnt + 2'd1;

if (current_balance >= TARIFF)

seg_data <= current_balance - TARIFF;

else

seg_data1 <= 4'b1100;

end

ACCESS_GRANTED: begin

if (cnt == 2'd3)

cnt <= 2'd0;

else

cnt <= cnt + 2'd1;

seg_data1 <= 4'b1011;

end

default: begin

cnt <= 2'd0;

seg_data <= 4'b1010;

end

endcase

end

endmodule

Файл top_metro.v: модуль top_metro является верхнеуровневым и осуществляет интеграцию всех компонентов системы.

module top_metro(

input clk,

input reset,

input T1,

input [2:0] balance,

output [6:0] seg_out,

output [6:0] seg_out1

)

wire slow_clk;

wire [3:0] fsm_seg_data;

wire [3:0] fsm_seg_data1;

// Делитель частоты

divider div_inst (

.clk_in(clk),

.reset(reset),

.clk_out(slow_clk)

);

// Конечный автомат метро

metro_fsm fsm_inst (

.clk(slow_clk),

.reset(reset),

.T1(T1),

.balance(balance),

.seg_data(fsm_seg_data),

.seg_data1(fsm_seg_data1)

);

// Декодеры для 7-сегментных индикаторов

coder seg_decoder (

.data(fsm_seg_data),

.seg(seg_out)

);

coder seg_decoder1 (

.data(fsm_seg_data1),

.seg(seg_out1)

);

endmodule

Файл metro_tb.v: модуль metro_tb служит для проверки корректности работы системы.

module metro_tb;

// Входы

reg clk;

reg reset;

reg T1;

reg [2:0] balance;

// Выходы

wire [6:0] seg_out;

wire [6:0] seg_out1;

top_metro uut (

.clk(clk),

.reset(reset),

.T1(T1),

.balance(balance),

.seg_out(seg_out),

.seg_out1(seg_out1)

);

initial begin

clk = 0;

forever #10 clk = ~clk;

end

// Test

initial begin

reset = 1;

T1 = 0;

balance = 3'b000;

#100;

reset = 0;

// Test 1

#100;

T1 = 1;

balance = 3'b111;

#200;

T1 = 0;

#500;

// Test 2

T1 = 1;

balance = 3'b100;

#200;

T1 = 0;

#800;

// Test 3

T1 = 1;

balance = 3'b001;

#200;

T1 = 0;

#800;

$finish;

end

endmodule

Временная диаграмма. На временной диаграмме представлена работа спроектированного конечного автомата для турникета метро. В начальный момент времени активен сигнал сброса (reset). После снятия сигнала сброса автомат начинает свою работу, последовательно переходя из одного состояния в другое в соответствии с заданным алгоритмом.

После снятия сброса автомат переходит в состояние WAIT_CARD. При активации сигнала T1 (прикладывание карты), автомат переходит в состояние READ_CARD, где происходит фиксация баланса. В состоянии DISPLAY_BALANCE происходит проверка баланса. Если баланс достаточен (как в тестах 1 и 2), на индикаторе seg_out отображается новый баланс (4 и 1 соответственно), а на seg_out1 — символ «G», и автомат переходит в ACCESS_GRANTED. Если баланс недостаточен (тест 3), на seg_out1 отображается символ «L», и автомат возвращается в WAIT_CARD.

Диаграмма демонстрирует корректность переходов между состояниями, работу счетчика задержек и формирование правильных выходных сигналов для индикаторов в зависимости от входных данных.

Рисунок 2. Wave

Вывод

В ходе выполнения лабораторной работы был успешно спроектирован и исследован конечный автомат, реализующий алгоритм контроля доступа для турникета метрополитена. Разработанное устройство демонстрирует корректную работу всех функциональных модулей.