Рисунок 4.4 - Результат верификации 4.5 Вывод
В ходе работы был разработан модуль, который выводит последовательность символов на матричный индикатор. В результате тестирования временная диаграмма показала корректную работу модуля. Также была изучена работа матричного индикатора и освоено написание тестовых модулей.
5 Проектирование модели многоканального генератора ШИМ-сигналов
5.1 Постановка задачи
В работе требуется реализовать в объёме ПЛИС Spartan-3E XC3S500E-4PQ208C модель логического устройства, сочетающую в себе функциональные узлы делителя частоты 1кГц, фильтра дребезга контактов кнопок и схемы динамической индикации, реализованных в предшествующих заданиях с новыми узлами генераторов широтно-импульсных сигналов. При этом все модули проекта должны быть описаны с помощью языка Verilog.
Помимо синтезируемых модулей, реализуемых в базисе элементов ПЛИС, в проекте следует разработать тестовый модуль, также написанный на языке Verilog, предназначенный для верификации.
5.2 Описание логического устройства
Центральным узлом схемы являлся 64-разрядный сдвиговый регистр. Исходное состояние сдвигового регистра определялось по персональному варианту, представленному в Таблице 1.1.
Во время штатного функционирования, при деактивированном сигнале сброса RST сдвиговый регистр способен выполнять две операции.
Первая операция – циклический сдвиг влево на 4 разряда, выполняется при «1» на входе SHIFT_4B_L, как показано на Рисунке 5.1.
Рисунок 5.1 — Операция сдвига влево
Вторая операция – циклический сдвиг вправо на 4 разряда, выполняется при «0» на входе SHIFT_4B_L и «1» на входе SHIFT_4B_R, как показано на Рисунке 5.2.
Рисунок 5.2 — Операция сдвига вправо
Сигналы, управляющие сдвиговым регистром, формировались фильтрами дребезга контактов по нажатию на две пользовательские кнопки.
Выходы сдвигового регистра подавались на два блока индикации.
Первый блок использовал светодиоды общего назначения, которые управляются в режиме регулировки яркости свечения с помощью широтно-импульсного сигнала.
Второй блок индикации использовал матричный индикатор, на который выводились все 64 разряда сдвигового регистра. Блок управления матричным индикатором работал аналогично работе из 4 раздела, однако вместо ПЗУ знакогенератора строками индикатора управляла комбинационная схема, коммутирующая разряды сдвигового регистра согласно Рисунку 5.3. Такая организация вывода позволяла увидеть изображение, выводимое на индикатор, непосредственно на временной диаграмме.
Рисунок 5.3 — Вывод содержимого регистра на матричный индикатор
Реализуемое в ПЛИС устройство имело структурную схему, представленную на Рисунке 5.4.
Рисунок 5.4 — Структурная схема синтезируемой части проекта
Таким же образом выглядит и тестовый модуль, однако в нем отсутствуют фильтры дребезга контактов кнопки.
Сдвиговый регистр, после снятия сигнала асинхронного сброса RST, должен был содержать значения, соответствующие персональному варианту, представленному в Таблице 1.1, как показано на Рисунке 5.5.
Рисунок 5.5 — Исходное состояние сдвигового регистра
В процессе выполнения работы было необходимо описать на языке Verilog модель генератора широтно-импульсного сигнала, отвечающую нижеизложенным требованиям. Состав сигналов (интерфейс) генератора широтно-импульсного сигнала показан на Рисунке 5.6.
Рисунок 5.6 — Интерфейс генератора широтно-импульсного сигнала
В итоге логическое устройство состояло из 6 основных модулей, а именно: модуля управления матричным индикатором, модуля генератора широтно-импульсных сигналов, фильтра дребезга контактов, делителя частоты, модуля верхнего уровня и тестового окружения.
5.3 Содержание модулей
Фильтр дребезга контактов и делитель частоты уже были описаны в разделе 2 и представлены в Листингах 2.2 и 2.3 соответственно.
В Листинге 5.1 представлен код модуля верхнего уровня иерархии проекта, описанный на языке Verilog. Он объединяет все используемые модули для корректной работы проекта, а также содержит реализацию сдвигового регистра.
Листинг 5.1 — Модуль верхнего уровня иерархии проекта (LR5_TOP.v)
module LR5_TOP(
input CLK,
input BTN_RST,
input BTN_L,
input BTN_R,
output [15:0] LED,
output [7:0] ROWS,
output [7:0] COLS
); reg RST_I;
always @(posedge CLK, negedge BTN_RST)
begin
if(BTN_RST) Продолжение Листинга 5.1
RST_I <= 1'b1;
else
RST_I <= 1'b0;
end
wire CE;
wire SHIFT_L_CE;
wire SHIFT_R_CE;
reg [63:0] SHIFT_REGISTER;
always @(posedge CLK, posedge RST_I)
//Исходное состояние - вариант
if(RST_I) SHIFT_REGISTER <= 64'hdc8d49aefd2daeea;
//Циклческий сдвиг влево
else if(SHIFT_L_CE) SHIFT_REGISTER <= {SHIFT_REGISTER[59:0], SHIFT_REGISTER[63:60]};
//Циклческий сдвиг вправо
else if(SHIFT_R_CE) SHIFT_REGISTER <= {SHIFT_REGISTER[3:0], SHIFT_REGISTER[63:4]};
LR5_CE CLK_DIV (
.CLK(CLK),
.RST(RST_I),
.CEO_DIV(CE)); LR5_BTN_FLTR BTN1FLTR (
.CLK(CLK),
.RST(RST_I),
.CE(CE),
.BTN_IN(BTN_L),
.BTN_OUT(),
.BTN_CEO(SHIFT_L_CE));
LR5_BTN_FLTR BTN2FLTR (
.CLK(CLK),
.RST(RST_I),
.CE(CE),
.BTN_IN(BTN_R),
.BTN_OUT(),
.BTN_CEO(SHIFT_R_CE));
PWM_FSM LED0(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[3:0]),
.PWM_P(LED[0]),
.PWM_N());
PWM_FSM LED1(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[7:4]),
.PWM_P(LED[1]),
.PWM_N());
PWM_FSM LED2(
.CLK(CLK),
.RST(RST_I),
Продолжение Листинга 5.1
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[11:8]),
.PWM_P(LED[2]),
.PWM_N());
PWM_FSM LED3(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[15:12]),
.PWM_P(LED[3]),
.PWM_N());
PWM_FSM LED4(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[19:16]),
.PWM_P(LED[4]),
.PWM_N());
PWM_FSM LED5(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[23:20]),
.PWM_P(LED[5]),
.PWM_N());
PWM_FSM LED6(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[27:24]),
.PWM_P(LED[6]),
.PWM_N());
PWM_FSM LED7(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[31:28]),
.PWM_P(LED[7]),
.PWM_N());
PWM_FSM LED8(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[35:32]),
.PWM_P(LED[8]),
.PWM_N());
PWM_FSM LED9(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[39:36]),
.PWM_P(LED[9]),
.PWM_N());
Продолжение Листинга 5.1
PWM_FSM LED10(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[43:40]),
.PWM_P(LED[10]),
.PWM_N());
PWM_FSM LED11(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[47:44]),
.PWM_P(LED[11]),
.PWM_N());
PWM_FSM LED12(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[51:48]),
.PWM_P(LED[12]),
.PWM_N());
PWM_FSM LED13(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[55:52]),
.PWM_P(LED[13]),
.PWM_N());
PWM_FSM LED14(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[59:56]),
.PWM_P(LED[14]),
.PWM_N());
PWM_FSM LED15(
.CLK(CLK),
.RST(RST_I),
.RE(RE),
.CE(CE),
.PWM_IN(SHIFT_REGISTER[63:60]),
.PWM_P(LED[15]),
.PWM_N());
MATRIXXX MATRIXXX(
.CLK(CLK),
.RST(RST_I),
.CE(CE),
.NMBR(SHIFT_REGISTER[63:0]),
.ROWS(ROWS),
.COLS(COLS));
endmodule Принцип широтно-импульсной модуляции – ШИМ (Pulse-Width Modulation – PWM) заключается в использовании двух уровней сигнала: низкого и высокого, или «0» и «1», соответственно, чередующихся с фиксированным периодом, но с различной длительностью каждого уровня в объёме периода. При этом могут быть два крайних состояния, когда весь период заполняется одним из двух уровней сигнала, при этом сигнал представляет собой константу, периодичность (частота) пропадает.
Наглядно принцип широтно-импульсной модуляции приведён на Рисунке 5.7.
Рисунок 5.7 — Принцип широтно-импульсной модуляции
Синтезируемая модель генератора ШИМ-сигналов имела параметр UDW, определяющий разрядность входной шины и число состояний управляющего автомата в объёме периода сигнала (частоту дискретизации). Именно этот параметр обеспечивает универсальность модели.
Число возможных входных комбинаций PWM_IN, задающих коэффициент заполнения периода активным уровнем сигнала («1» - для PWM_P, «0» - для PWM_N), составляло 2UDW штук. При этом комбинация из всех «0» задаёт коэффициент 0%, а комбинация из всех «1» – коэффициент 100%. Период выходного сигнала делится на (2UDW – 1) равных тактов, заданных частотой сигнала разрешения синхронизации CE, либо равных периоду синхросигнала CLK, если на вход CE подана константа «1». Таким образом, частота выходного ШИМ-сигнала получается из частоты дискретизации (частоты CE или CLK при CE = «1») путём деления на коэффициент (2UDW – 1).
По умолчанию значение параметра UDW составляло 4. Для 4-разрядной входной шины возможны 16 различных входных комбинаций, определяющих значения выходного сигнала на 15 тактах в течение одного периода работы генератора ШИМ.
Функциональная схема генератора ШИМ-сигналов приведена на Рисунке 5.8. Входной регистр PWM_REG обеспечивает хранение управляющей комбинации в течение периода работы генератора. Формирование выходных сигналов осуществляет конечный автомат с числом состояний 2UDW.
Рисунок 5.8 — Функциональная схема генератора
Граф переходов конечного автомата показан на Рисунке 5.9.
Рисунок 5.9 — Граф переходов конечного автомата
Состояние входного регистра изменяется в последнем такте предпоследнего состояния автомата (2UDW - 2). Входной регистр позволяет закончить период генерации ШИМ-сигнала на основе неизменной управляющей комбинации, зафиксированной перед началом текущего периода. Период генерации начинается в состоянии 2UDW – 1 и заканчивается в состоянии 2UDW – 2. Таким образом, изменения комбинации на входе PWM_IN не приведут к искажению формы выходного сигнала.
Вход синхронного сброса RE предназначен для возврата автомата в исходное состояние-0 и для перевода выходов в пассивное состояние. Синхронный сброс является приоритетной операцией и воздействует независимо от разрешения синхронизации CE. На входной регистр PWM_REG синхронный сброс не оказывает воздействия.
В итоге, после учёта всех вышеперечисленных требований, был написан модуль, представленный на Листинге 5.2.
Листинг 5.2 — Модуль ШИМ-генератора (PWM_FSM.v)
module PWM_FSM#(
parameter UDW = 4
)
(
input CLK,
input RST,
input RE,
input CE,
input [UDW-1:0] PWM_IN,
output reg PWM_P,
output reg PWM_N
);
//входной регистр и регистр состояния конечного автомата
reg [UDW-1:0] PWM_REG;
reg [UDW-1:0] FSM_STATE;
//граф
always @(posedge CLK, posedge RST) begin
if(RST)
PWM_REG <= 0;
else if(CE && (FSM_STATE == (2**UDW) - 2))
PWM_REG <= PWM_IN;
end always @(posedge CLK, posedge RST) begin
if(RST) begin
//«действия по асинхронному сбросу»
PWM_P <= 1'b0;
PWM_N <= 1'b1;
FSM_STATE <= {UDW{1'b0}};
end
else if(RE) begin
Продолжение Листинга 5.2
//«действия по синхронному сбросу»
PWM_P <= 1'b0;
PWM_N <= 1'b1;
FSM_STATE <= {UDW{1'b0}};
end
else if(CE) begin
case(FSM_STATE)
0: begin
//«действия в состоянии-0»
PWM_P <= 1'b0;
PWM_N <= 1'b1;
FSM_STATE <= 2**UDW-2;
end
{UDW{1'b1}}: begin
//«действия в состоянии 11…111»
if(PWM_REG == 0) begin
PWM_P <= 1'b0;
PWM_N <= 1'b1;
end
else begin
PWM_P <= 1'b1;
PWM_N <= 1'b0;
end
FSM_STATE <= 1;
end
default: begin
//«действия в промежуточном состоянии»
if(PWM_REG > FSM_STATE) begin
PWM_P <= 1'b1;
PWM_N <= 1'b0;
end
else begin
PWM_P <= 1'b0;
PWM_N <= 1'b1;
end
FSM_STATE <= FSM_STATE + 1'b1;
end
endcase
end
end
endmodule
Модуль управления матричным индикатором был описан в разделе 4, однако логика его работы незначительно изменилась, поэтому код данного модуля представлен в Листинге 5.3.
Листинг 5.3 — Модуль управления матричным индикатором (MATRIXXX.v)
module MATRIXXX(
input CLK,
input RST,
input CE,
input [63:0] NMBR,
output reg [7:0] ROWS,
output reg [7:0] COLS
); reg [2:0]CT_CO; // Счетчик столбцов
always @(posedge CLK, posedge RST) Продолжение Листинга 5.3
begin
if(RST) begin
CT_CO <= 0;
end
else
if(CE) begin
CT_CO <= CT_CO + 1'b1;
end
end // Дешифратор столбцов
always @*
case(CT_CO)
3'd0: COLS <= 8'b11111110;
3'd1: COLS <= 8'b11111101;
3'd2: COLS <= 8'b11111011;
3'd3: COLS <= 8'b11110111;
3'd4: COLS <= 8'b11101111;
3'd5: COLS <= 8'b11011111;
3'd6: COLS <= 8'b10111111;
default: COLS <= 8'b01111111;
endcase // ПЗУ знакогенератор
always @* begin
case(CT_CO)
//{NMBR[], NMBR[], NMBR[], NMBR[], NMBR[], NMBR[], NMBR[], NMBR[]};
7'h0: ROWS <= {NMBR[63], NMBR[55], NMBR[47], NMBR[39], NMBR[31], NMBR[23], NMBR[15], NMBR[7]};
7'h1: ROWS <= {NMBR[62], NMBR[54], NMBR[46], NMBR[38], NMBR[30], NMBR[22], NMBR[14], NMBR[6]};
7'h2: ROWS <= {NMBR[61], NMBR[53], NMBR[45], NMBR[37], NMBR[29], NMBR[21], NMBR[13], NMBR[5]};
7'h3: ROWS <= {NMBR[60], NMBR[52], NMBR[44], NMBR[36], NMBR[28], NMBR[20], NMBR[12], NMBR[4]};
7'h4: ROWS <= {NMBR[59], NMBR[51], NMBR[43], NMBR[35], NMBR[27], NMBR[19], NMBR[11], NMBR[3]};
7'h5: ROWS <= {NMBR[58], NMBR[50], NMBR[42], NMBR[34], NMBR[26], NMBR[18], NMBR[10], NMBR[2]};
7'h6: ROWS <= {NMBR[57], NMBR[49], NMBR[41], NMBR[33], NMBR[25], NMBR[17], NMBR[9], NMBR[1]};
///7'h7: ROWS <= {NMBR[56], NMBR[48], NMBR[40], NMBR[32], NMBR[24], NMBR[16], NMBR[8], NMBR[0]};
default: ROWS <= {NMBR[56], NMBR[48], NMBR[40], NMBR[32], NMBR[24], NMBR[16], NMBR[8], NMBR[0]};
endcase
end endmodule
|