Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

неелова_лабы / 5laba / отчет_лаба_5_вычтехн

.docx
Скачиваний:
1
Добавлен:
26.12.2024
Размер:
243.32 Кб
Скачать

Отчёт к лабораторной работе №5

“Сборка и проверка работоспособности многомодульного устройства”

Введение

Цель данной лабораторной работы — разработать и смоделировать многомодульное устройство на языке Verilog по заданной схеме. Устройство состоит из нескольких модулей, таких как защелки, кодер, буфер, мультиплексор и конечный автомат. В отчете представлены все этапы моделирования, включая блок-схемы модулей и функциональные диаграммы.

Описание устройств

Устройство предназначено для приема 4-битных входных данных, их обработки и передачи на выходной модуль parser. Основные компоненты устройства:

  • Защелка (latch): хранит входные данные.

  • Кодер (coder4x5): преобразует 4-битные данные в 5-битные.

  • Буфер (bufer5x4): временно хранит данные для дальнейшей обработки.

  • Мультиплексор (mpl): выбирает один из нескольких входов для передачи на выход.

  • Конечный автомат (fsm): управляет работой устройства, контролируя сигналы записи и чтения, а также выбирая команды для мультиплексора.

Функциональная схема кодера 4x5:

Модуль coder4x5

Назначение

Модуль coder4x5 предназначен для преобразования 4-битного входного сигнала data4 в 5-битный выходной сигнал data5 на основе предопределенной таблицы кодирования. Это позволяет расширить разрядность данных и выполнить определенное кодирование для последующей обработки.

Входы и выходы

  • Входы:

    • data4[3:0]: 4-битный входной сигнал.

  • Выходы:

    • data5[4:0]: 5-битный выходной сигнал.

Код:

module coder4x5 (

input wire [3:0] data4,

output wire [4:0] data5

);

reg [4:0] code; // для хранения состояний выходов

assign data5 = code;

always @* begin

case (data4)

4'b0000: code = 5'b11110;

4'b0001: code = 5'b01001;

4'b0010: code = 5'b10100;

4'b0011: code = 5'b10101;

4'b0100: code = 5'b01010;

4'b0101: code = 5'b01011;

4'b0110: code = 5'b01110;

4'b0111: code = 5'b01111;

4'b1000: code = 5'b10010;

4'b1001: code = 5'b10011;

4'b1010: code = 5'b10110;

4'b1011: code = 5'b10111;

4'b1100: code = 5'b11010;

4'b1101: code = 5'b11011;

4'b1110: code = 5'b11100;

4'b1111: code = 5'b11101;

default: code = 5'b00000; // значение по умолчанию на случай ошибки

endcase

end

endmodule

Функциональная схема мультиплексора:

Модуль mpl (Мультиплексор)

Назначение

Модуль mpl реализует 4-входовый мультиплексор, который на основе управляющего сигнала send_cmd выбирает один из четырех 5-битных входов и передает его на выход line.

Входы и выходы

  • Входы:

    • in0[4:0]: Первый входной сигнал.

    • in1[4:0]: Второй входной сигнал.

    • in2[4:0]: Третий входной сигнал.

    • in3[4:0]: Четвертый входной сигнал.

    • send_cmd[1:0]: 2-битный управляющий сигнал для выбора одного из входов.

  • Выходы:

    • line[4:0]: Выбранный выходной сигнал.

Код:

module mpl (

input [4:0] in0, // ???? 0 (5-?????????)

input [4:0] in1, // ???? 1 (5-?????????)

input [4:0] in2, // ???? 2 (5-?????????)

input [4:0] in3, // ???? 3 (5-?????????)

input [1:0] send_cmd, // ??????? ?????? (2 ???? ??? ?????? ?????? ?? 4 ??????)

output [4:0] line // ???????? ????? (5-?????????)

);

reg [4:0] mux_out; // ?????? ??? ???????? ?????????? ????? (?????? ????? cell)

// ???????????? ???????? mux_out ???????? ?????

assign line = mux_out;

// ???? always ??? ???????????? ???????? ? ??????????? ?? ???????

always @(*) begin

case (send_cmd)

2'b00: mux_out = in0; // ???? ??????? 00, ?? ????? ?????????? in0

2'b01: mux_out = in1; // ???? ??????? 01, ?? ????? ?????????? in1

2'b10: mux_out = in2; // ???? ??????? 10, ?? ????? ?????????? in2

2'b11: mux_out = in3; // ???? ??????? 11, ?? ????? ?????????? in3

default: mux_out = 5'b00000; // ???????? ?? ????????? ? 5 ?????

endcase

end

endmodule

Модуль latch (Защелка)

Функциональная схема защёлки:

Назначение

Модуль latch предназначен для хранения входных данных при нарастании тактового сигнала clk. Это стандартная D-защелка.

Параметры

  • parameter N = 4: Параметризированная ширина входных и выходных данных.

Входы и выходы

  • Входы:

    • clk: Тактовый сигнал.

    • d_in[N-1:0]: Входные данные шириной N бит.

  • Выходы:

    • d_out[N-1:0]: Выходные данные шириной N бит.

Код:

`timescale 1ns/100ps

module latch #(parameter N = 4) (

input wire clk,

input wire [N-1:0] d_in,

output reg [N-1:0] d_out

);

always @(posedge clk) begin

d_out <= d_in;

end

endmodule

Модуль bufer5x4 (Буфер)

Функциональная схема буфера

Назначение

Модуль bufer5x4 реализует сдвиговый регистр или буфер глубиной 4, который хранит последовательность из четырех 5-битных значений. Он позволяет записывать новые данные и читать их в порядке поступления.

Входы и выходы

  • Входы:

    • clk: Тактовый сигнал.

    • reset: Сигнал сброса.

    • wr: Сигнал разрешения записи.

    • rd: Сигнал разрешения чтения.

    • data_in[4:0]: Входные данные.

  • Выходы:

    • data_out[4:0]: Выходные данные.

Код:

module bufer5x4 (

input wire clk, // ???????? ??????

input wire reset, // ?????? ??????

input wire wr, // ?????????? ??????

input wire rd, // ?????????? ??????

input wire [4:0] data_in, // ??????? ??????

output wire [4:0] data_out // ???????? ??????

);

// ?????????? ??????????

reg [4:0] shift_reg[3:0]; // 4 ??????????? ?????? ??? ???????? ??????

integer i;

// ??????????? ????? ???????? ????????? ??????

assign data_out = shift_reg[3];

// ???? ??????, ? ????????????????? ? posedge clk ? posedge reset

always @(posedge clk or posedge reset) begin

if (reset) begin

// ??? ?????? ???????? ??? ????????

for (i = 0; i < 4; i = i + 1) begin

shift_reg[i] <= 5'd0;

end

end else begin

// ?????? ?????? (wr) ??? ?????? (rd)

if (wr) begin

// ?????????? ?????? ?? ??? ?????? ??????

for (i = 1; i < 4; i = i + 1) begin

shift_reg[i] <= shift_reg[i-1];

end

shift_reg[0] <= data_in;

end else if (rd) begin

// ???????? ?????? ?? ?????

for (i = 1; i < 4; i = i + 1) begin

shift_reg[i] <= shift_reg[i-1];

end

shift_reg[0] <= 5'd0; // ???????? ?? ???? ??? ??????

end

end

end

endmodule

Модуль fsm (Конечный автомат)

Функциональная схема конечного автомата:

Назначение

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

Входы и выходы

  • Входы:

    • clk: Тактовый сигнал.

    • Reset (res): Сигнал сброса.

    • data_wr (wr_en): Сигнал разрешения записи данных.

  • Выходы:

    • buf_wr: Сигнал записи в буфер.

    • buf_rd: Сигнал чтения из буфера.

    • adr[1:0]: Управляющий сигнал для мультиплексора.

    • state[2:0]: Текущее состояние автомата.

    • data_cnt[3:0]: Счетчик количества записанных данных.

Код:

module fsm(

input clk, // Синхроимпульс

input reset, // Сигнал сброса

input data_wr, // Сигнал разрешения записи

output reg wr, // Сигнал записи

output reg rd, // Сигнал чтения

output reg [1:0] adr // Адрес для мультиплексора

);

// Внутренние регистры

reg [2:0] state; // Регистр состояния

reg [3:0] data_cnt; // Регистр счетчика буфера (должен считать до 4)

// Определение параметров для состояний

parameter S0 = 3'd0,

S1 = 3'd1,

S2 = 3'd2,

S3 = 3'd3,

S4 = 3'd4,

S5 = 3'd5,

S6 = 3'd6;

// Определение параметров для команд

parameter CMD_START = 2'b00,

CMD_DATA = 2'b01,

CMD_STOP = 2'b10,

CMD_IDLE = 2'b11;

// Блок формирования смены состояний (переходов)

always @(posedge clk or posedge reset)

begin

if (reset)

state <= S0; // Сброс в начальное состояние

else

begin

case (state)

S0: state <= S1; // После сброса переход в S1

S1: if (data_wr)

state <= (data_cnt == 4) ? S4 : S2; // Если data_cnt=4, переходим в S4 (стартовая посылка), иначе в S2 (запись данных)

else

state <= S1; // Ожидание разрешения записи

S2: if (data_cnt < 4)

state <= S2; // Продолжаем запись данных, пока data_cnt < 4

else

state <= S4; // Переход в стартовую посылку после завершения записи

S4: state <= S5; // Переход в S5 для стартовой посылки

S5: if (data_cnt == 1)

state <= S6; // Если data_cnt=1, переход в стоповую посылку

else

state <= S5; // Продолжение посылки данных

S6: state <= S1; // Переход обратно в S1 после стоповой посылки

default: state <= S0; // Защита на случай неизвестного состояния

endcase

end

end

// Блок описания действий исполнительного устройства

always @(posedge clk or posedge reset)

begin

if (reset)

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_IDLE;

data_cnt <= 4'd0; // Счетчик должен обнуляться при сбросе

end

else

begin

case (state)

S0: // Состояние сброса

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_IDLE;

data_cnt <= 4'd0; // Обнуление счетчика в состоянии сброса

end

S1: // Ожидание разрешения записи

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_IDLE;

end

S2: // Запись данных

begin

wr <= 1'b1; // Установка сигнала записи

rd <= 1'b0; // Сигнал чтения должен быть 0

adr <= CMD_DATA; // Установка адреса для передачи данных

if (data_cnt < 4)

data_cnt <= data_cnt + 1; // Увеличение счетчика, пока он меньше 4

end

S4: // Стартовая посылка

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_START; // Установка адреса для стартовой посылки

end

S5: // Посылка данных

begin

wr <= 1'b0; // Сигнал записи должен быть 0

rd <= 1'b1; // Установка сигнала чтения

adr <= CMD_DATA; // Установка адреса для передачи данных

if (data_cnt > 1)

data_cnt <= data_cnt - 1; // Уменьшение счетчика

else

data_cnt <= 4'd0; // Обнуление счетчика, когда data_cnt <= 1

end

S6: // Стоповая посылка

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_STOP; // Установка адреса для стоповой посылки

data_cnt <= 4'd0; // Обнуление счетчика в конце

end

default: // Защита на случай неизвестного состояния

begin

wr <= 1'b0;

rd <= 1'b0;

adr <= CMD_IDLE;

data_cnt <= 4'd0;

end

endcase

end

end

endmodule

Модуль controller (Контроллер)

Функциональная схема контроллера:

Назначение

Модуль controller является верхнеуровневым модулем, объединяющим все ранее описанные модули. Он обеспечивает полную функциональность устройства, обрабатывая входные данные, кодируя их, буферизуя и управляя передачей данных на выходной модуль parser.

Входы и выходы

  • Входы:

    • clk: Тактовый сигнал.

    • reset: Сигнал сброса.

    • data_in[3:0]: Входные данные.

    • data_wr: Сигнал разрешения записи.

  • Выходы:

    • parser_out[4:0]: Выходные данные для модуля parser.

    • fsm_state[2:0]: Текущее состояние конечного автомата.

Внутренние сигналы

  • data5[4:0]: Выходные данные от кодера.

  • buffer_out[4:0]: Выходные данные из буфера.

  • mpl_out[4:0]: Выход мультиплексора.

  • latch5_out[4:0]: Выходная защелка.

  • buf_write: Сигнал записи в буфер.

  • buf_read: Сигнал чтения из буфера.

  • send_cmd[1:0]: Команда для мультиплексора.

  • data_cnt[3:0]: Счетчик данных из FSM.

  • state_fsm[2:0]: Текущее состояние FSM.

Симуляция контроллера.

// controller.v

`timescale 1ns/1ps

module controller (

input wire clk, // Тактовый сигнал

input wire reset, // Сигнал сброса

input wire [3:0] data_in, // Входные данные (4-битные)

input wire data_wr, // Сигнал разрешения записи

output wire [4:0] parser_out, // Выходные данные на модуль parser

output wire [2:0] fsm_state // Новый выход для состояния FSM

);

// Внутренние сигналы

wire [4:0] data5;

wire [4:0] buffer_out;

wire [4:0] mpl_out;

wire [4:0] latch5_out;

wire buf_write, buf_read;

wire [1:0] send_cmd;

wire [3:0] data_cnt;

wire [2:0] state_fsm; // Внутренний сигнал для состояния FSM

// Модуль защелки для хранения входных данных

wire [3:0] data_out_rgstr;

latch #(.N(4)) latch_rgstr_inst (

.clk(clk),

.d_in(data_in),

.d_out(data_out_rgstr)

);

// Модуль кодера

coder4x5 coder_inst (

.data4(data_out_rgstr), // Используем данные из защёлки

.data5(data5)

);

// Модуль буфера

bufer5x4 buffer_inst (

.clk(clk),

.reset(reset),

.wr(buf_write),

.rd(buf_read),

.data_in(data5),

.data_out(buffer_out)

);

// Мультиплексор

mpl mpl_inst (

.in0(5'b00110),

.in1(data5),

.in2(5'b01101), // CMD_START

.in3(5'b11111), // CMD_STOP

.send_cmd(send_cmd),

.line(mpl_out)

);

// Защелка для регистрации данных из мультиплексора

latch #(.N(5)) latch5_inst (

.clk(clk),

.d_in(mpl_out),

.d_out(latch5_out)

);

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

fsm fsm_inst (

.clk(clk),

.reset(reset),

.data_wr(data_wr), // Подключаем внешний сигнал

.buf_wr(buf_write),

.buf_rd(buf_read),

.adr(send_cmd),

.state(state_fsm), // Подключение сигнала state

.data_cnt(data_cnt)

);

// Присваиваем внутренний сигнал выходу

assign fsm_state = state_fsm;

// Модуль parser (предполагается, что он реализован отдельно)

// Подключение выхода из latch5 к parser

// Если модуль parser отсутствует, можно напрямую присвоить:

assign parser_out = latch5_out;

endmodule

Тестбенч для модуля контоллера:

// controller_tb.v

`timescale 1ns/1ps

module controller_tb;

// Входы

reg clk;

reg reset;

reg [3:0] data_in;

reg data_wr; // Сигнал разрешения записи

// Выходы

wire [4:0] parser_out;

wire [2:0] fsm_state; // Выход состояния FSM

// Параметры тактового сигнала

parameter PERIOD = 10;

// Инстанцирование верхнеуровневого модуля

controller uut (

.clk(clk),

.reset(reset),

.data_in(data_in),

.data_wr(data_wr), // Подключаем сигнал data_wr

.parser_out(parser_out),

.fsm_state(fsm_state) // Подключение нового выхода

);

// Генерация тактового сигнала

initial begin

clk = 0;

forever #(PERIOD/2) clk = ~clk;

end

// Инициализация и тестирование

initial begin

// Инициализация входов

reset = 1;

data_in = 4'b0000;

data_wr = 0; // Изначально запись запрещена

#(PERIOD);

// Сброс

reset = 0;

#(PERIOD);

// Цикл записи данных

// Для каждой записи:

// 1. Разрешить запись (data_wr = 1)

// 2. Установить данные на data_in

// 3. Удерживать состояние записи на 2 такта

// 4. Запретить запись на 10-15 тактов

// Запись 1

@(posedge clk);

data_in = 4'b0001; // Данные для записи

data_wr = 1; // Разрешаем запись

#(2 * PERIOD); // Удерживаем на 2 такта

data_wr = 0; // Запрещаем запись

#(12 * PERIOD); // Запрет на 12 тактов

// Запись 2

@(posedge clk);

data_in = 4'b0010;

data_wr = 1;

#(2 * PERIOD);

data_wr = 0;

#(12 * PERIOD);

// Запись 3

@(posedge clk);

data_in = 4'b0011;

data_wr = 1;

#(2 * PERIOD);

data_wr = 0;

#(12 * PERIOD);

// Запись 4

@(posedge clk);

data_in = 4'b0100;

data_wr = 1;

#(2 * PERIOD);

data_wr = 0;

#(12 * PERIOD);

// Запись 5

@(posedge clk);

data_in = 4'b0101;

data_wr = 1;

#(2 * PERIOD);

data_wr = 0;

#(12 * PERIOD);

// После последней записи, дайте серию повторов для считывания

#(20 * PERIOD);

// Завершение симуляции

$stop;

end

endmodule

Вывод: Было смоделировано устройство, состоящее из нескольких модулей: защёлки, кодера, буфера, мультиплексора и конечного автомата. Устройство принимает 4-битные входные данные по линии data_in и обрабатывает их в соответствии с заданной логикой. После обработки данные выводятся по линии parser_out, обеспечивая взаимодействие с модулем-приёмником. В рамках лабораторной работы №5 были разработаны и протестированы эти модули на языке Verilog, а также реализовано их объединение в единое устройство согласно заданной схеме.

Соседние файлы в папке 5laba