Материал: ППЭВС. Курсовая работа (пример)

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Последовательный вывод на индикаторах:

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