Главная страница
Навигация по странице:

  • Рисунок 2.3 — RTL-модель верхнего уровня иерархии

  • Рисунок 2.4 — Граф переходов автомата 2.3 Содержание модулей

  • 2.4 Тестовое окружение и результат верификации

  • Рисунок 2.6 — Результат верификации 2.5 Вывод

  • 3 Разработка цифрового узла анализатора последовательности 3.1 Постановка задачи

  • Рисунок 3.1 — Интерфейс модели цифрового узла

  • Рисунок 3.2 — Алгоритм распознавания последовательности

  • Рисунок 3.3 — Структурная схема автомата

  • Рисунок 3.4 — Выводы семисегментного индикатора 3.3 Содержание модулей

  • курс. курсач_борон_даня. Содержание х1Х0 13 Х3Х2 13 00 13 01 13


    Скачать 1.9 Mb.
    НазваниеСодержание х1Х0 13 Х3Х2 13 00 13 01 13
    Дата16.11.2022
    Размер1.9 Mb.
    Формат файлаdocx
    Имя файлакурсач_борон_даня.docx
    ТипДокументы
    #791937
    страница3 из 6
    1   2   3   4   5   6


    Рисунок 2.2 — Интерфейс модуля верхнего уровня


    Рисунок 2.3 — RTL-модель верхнего уровня иерархии

    Помимо этого, требовалось построить граф переходов автомата для прямой и обратной генерации. С его помощью можно нагляднее рассмотреть и оценить ход работы автомата. Граф переходов представлен на Рисунке 2.4.



    Рисунок 2.4 — Граф переходов автомата

    2.3 Содержание модулей

    Во-первых, нужно было разработать сам модуль конечного автомата. Переход состояний был реализован через оператор “case”, который меняет состояния автомата в зависимости от значения переменной “cnt”. Эта переменная меняется в зависимости от сигнала “UP”, если он равен 1, то “cnt” инкрементируется, в противном случае — декрементируется. Помимо этого, был добавлен сброс “cnt” при положительном “RST”. Также, реализована загрузка состояния из “DAT_I” в “cnt”. Код модуля конечного автомата представлен на Листинге 2.1.

    Листинг 2.1 — Модуль конечного автомата (MAIN_MODULE.v)

    module MAIN_MODULE(

    input CLK,

    input RST,

    input CE,

    input LOAD,

    input [3:0] DAT_I,

    input UP,

    output reg [3:0] SEQ

    );
    reg [3:0] cnt;
    always@(cnt)

    case(cnt)

    4'h0: SEQ <= 4'hD;

    4'h1: SEQ <= 4'hC;

    4'h2: SEQ <= 4'h8;

    4'h3: SEQ <= 4'hD;
    4'h4: SEQ <= 4'h4;

    4'h5: SEQ <= 4'h9;

    4'h6: SEQ <= 4'hA;

    4'h7: SEQ <= 4'hE;

    4'h8: SEQ <= 4'hF;

    4'h9: SEQ <= 4'hD;

    4'hA: SEQ <= 4'h2;

    4'hB: SEQ <= 4'hD;

    4'hC: SEQ <= 4'hA;

    4'hD: SEQ <= 4'hE;

    4'hE: SEQ <= 4'hE;

    4'hF: SEQ <= 4'hA; default: SEQ <= 4'h0;

    endcase
    always@(posedge CLK or posedge RST)

    if (RST)

    cnt <= 4'h0;

    else if (LOAD)

    cnt <= DAT_I;

    else if (CE)

    if (UP)

    cnt<=(cnt + 1);

    else

    cnt <= (cnt - 1);

    else SEQ <= SEQ;

    endmodule

    Помимо модуля конечного автомата, требовалось разработать модули фильтра дребезга контактов и делителя частоты. Дребезг контактов  — явление, происходящее в электромеханических коммутационных устройствах и аппаратах (кнопках, реле, герконах, переключателях, контакторах, магнитных пускателях и др.), длящееся некоторое время после замыкания электрических контактов. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счёт упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь. То есть, во время нажатия на кнопку, система будет фиксировать огромное количество нажатий.

    Фильтр дребезга контактов используется для устранения такого неприятного эффекта. Суть заключается в том, что есть внутренний счётчик, который отсчитывает число. Это число должно быть больше, чем время случайного соприкосновения контактов, но меньше времени, которое контакты соприкасаются при нажатии человеком. Тогда, если счётчик досчитал до этого числа, то кнопка действительно нажата и следует подать соответствующий сигнал.

    Помимо этого, для корректной работы светодиодов нужен делитель частоты. Тактовый генератор на отладочной плате имеет частоту 100 МГц, что слишком много. Подобрать частоту мерцания светодиодов нужно так, чтобы глаз различал только постоянное горение светодиода. Оптимальным значением будет 1кГц.

    Данные модули были разработаны и реализованы. Код модулей представлен в листингах 2.2 и 2.3 соответственно.

    Листинг 2.2 — Модуль фильтра дребезга контактов (BTN_FILTER_CE.v)

    module BTN_FILTER_CE(

    input CLK,

    input CE,

    input BTN_IN,

    input RST,

    output reg BTN_CEO

    );
    parameter [3:0] CNTR_WIDTH = 4; // Internal Counter Width

    // Internal signals declaration:

    reg [CNTR_WIDTH - 1:0] FLTR_CNT;

    reg BTN_D, BTN_S1, BTN_S2;

    //-----------------------------------------

    // Main Counter:

    always @ (posedge CLK, posedge RST)

    if(RST) FLTR_CNT <= {CNTR_WIDTH{1'b0}};

    else

    if(!(BTN_S1 ^ BTN_S2)) // if BTN_S1 = BTN_S2

    FLTR_CNT <= {CNTR_WIDTH{1'b0}}; // Return to Zero

    else if(CE) // else if Clock Enable

    FLTR_CNT <= FLTR_CNT + 1; // Increment

    //-----------------------------------------

    // Input Synchronizer:

    always @ (posedge CLK, posedge RST)

    if(RST)
    Продолжение Листинга 2.2

    begin

    BTN_D <= 1'b0;

    BTN_S1 <= 1'b0;

    end

    else

    begin

    BTN_D <= BTN_IN;

    BTN_S1 <= BTN_D;

    end

    //-----------------------------------------

    // Output Register:

    always @ (posedge CLK, posedge RST)

    if(RST) BTN_S2 <= 1'b0;

    else if(&(FLTR_CNT) & CE) BTN_S2 <= BTN_S1;

    //-----------------------------------------

    // Output Front Detector Clock Enable:

    always @ (posedge CLK, posedge RST)

    if(RST) BTN_CEO <= 1'b0;

    else BTN_CEO <= &(FLTR_CNT) & CE & BTN_S1;

    //------------------------------------------

    endmodule

    Листинг 2.3 — Модуль делителя частоты (DIV_CLK.v)

    module DIV_CLK(

    input CLK,

    input RST,

    output reg CLK_OUT

    );
    reg [13:0] cnt;
    always@(posedge CLK or posedge RST) begin

    if (RST) begin

    cnt <= 0;

    CLK_OUT <= 1'b0;

    end

    else if (cnt == 100000) begin cnt <= 0; CLK_OUT <= 1'b1; end

    else begin cnt <= cnt + 1; CLK_OUT <= 1'b0; end

    end
    //assign CLK_OUT = (cnt == 0) ? 1 : 0;
    endmodule

    Также был реализован модуль для обработки нажатия кнопки сброса (Листинг 2.4).

    Листинг 2.4 — Модуль обработки нажатия кнопки reset (RST_MODULE.v)

    module RST_MODULE(

    input CLK,

    input R,

    output reg Q_RST

    );

    always @(posedge CLK or negedge R) begin

    if (!R) Q_RST <= 1'b1;

    else Q_RST <= 1'b0;

    end

    endmodule
    Затем, нужно было объединить все вышеперечисленные модули в одном модуле верхнего уровня, представленного в Листинге 2.5.

    Листинг 2.5 — Модуль верхнего уровня (TOP.v)

    module TOP(

    input CPU_RESET,

    input CLK,

    input BTN_C,

    input BTN_U,

    input [4:0] SW,

    output [3:0] LED

    );

    wire line_RST;

    wire line_CLK;

    wire line_CE;

    wire line_LOAD;
    RST_MODULE FB1(

    .CLK(CLK),

    .R(CPU_RESET),

    .Q_RST(line_RST)

    );
    DIV_CLK FB2(

    .RST(line_RST),

    .CLK(CLK),

    .CLK_OUT(line_CLK)

    );
    BTN_FILTER_CE FB3(

    .CLK(CLK),

    .CE(line_CLK),

    .BTN_IN(BTN_C),

    .RST(line_RST),

    .BTN_CEO(line_CE)

    );
    BTN_FILTER_LOAD FB4(

    .CLK(CLK),

    .CE(line_CLK),

    .BTN_IN(BTN_U),

    .RST(line_RST),

    .BTN_CEO(line_LOAD)

    );
    MAIN_MODULE FB5(

    .CLK(CLK),

    .RST(line_RST),

    .CE(line_CE),

    .LOAD(line_LOAD),

    .DAT_I(SW[3:0]),

    .UP(SW[4]),

    .SEQ(LED[3:0])

    );

    endmodule

    2.4 Тестовое окружение и результат верификации

    В Листинге 2.6 описан модуль тестового окружения для тестирования работы моделей проекта и верификации проделанной работы.

    Листинг 2.6 — Тестовый модуль (Test_MAIN.v)

    module Test_MAIN;
    // Inputs

    reg CLK;

    reg RST;

    reg CE;

    reg LOAD;

    reg [3:0] DAT_I;

    reg UP;
    // Outputs

    wire [3:0] SEQ;
    // Instantiate the Unit Under Test (UUT)

    MAIN_MODULE uut (

    .CLK(CLK),

    .RST(RST),

    .CE(CE),

    .LOAD(LOAD),

    .DAT_I(DAT_I),

    .UP(UP),

    .SEQ(SEQ)

    );
    initial begin

    // Initialize Inputs

    CLK = 0;

    RST = 1;

    CE = 0;

    LOAD = 0;

    DAT_I = 0;

    UP = 0;
    // Wait 100 ns for global reset to finish

    #150;

    RST = 0;

    CE = 1;

    LOAD = 0;

    DAT_I = 0;

    UP = 1;

    #150;

    UP = 0;

    #150;

    CE = 0;

    LOAD = 1;

    DAT_I = 4'b1000;

    #150;

    CE = 0;

    LOAD = 0;

    Продолжение Листинга 2.6

    DAT_I = 0;

    UP = 0;

    // Add stimulus here
    end
    always

    begin

    #5;

    CLK <=

    CLK;

    end

    endmodule

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



    Рисунок 2.6 — Результат верификации

    2.5 Вывод

    В результате был спроектирован конечный автомат, представляющий собой генератор фиксированной последовательности логических сигналов, в виде синтезируемой модели на языке Verilog HDL. Также было реализовано на этом языке тестовое окружение и успешно проведена верификация спроектированной модели при помощи симулятора iSim из состава САПР Xilinx ISE Design Suite.

    3 Разработка цифрового узла анализатора последовательности

    3.1 Постановка задачи

    Требовалось разработать цифровой узел на основе отладочной платы Digilent Nexys 4, представляющий собой анализатор фиксированной последовательности логических сигналов. Узел должен обеспечивать индикацию ожидаемых и вводимых элементов последовательности посредством входящих в состав отладочной платы семисегментных индикаторов согласно данному заданию.

    Узел должен быть реализован в виде синтезируемой модели на языке Verilog HDL.

    Интерфейс верхнего уровня иерархии модели должен состоять из набора сигналов, представленного на Рисунке 3.1.



    Рисунок 3.1 — Интерфейс модели цифрового узла

    Очередной элемент последовательности для анализа подается на входы узла SW[3:0] с соответствующих движковых переключателей отладочной платы. Загрузка элемента подтверждается однократным нажатием кнопки BTN_C, сигнал от которой подается на вход узла. В связи с этим следует обеспечивать защиту от дребезга контактов кнопки.

    Алгоритм работы цифрового узла представлен на Рисунке 3.2. Значение Х представляет собой номер элемента цифровой последовательности, ввод значения которого (Y) ожидается. Значения Y каждого элемента цифровой последовательности определяются вариантом задания, представленным в Таблице 1.1.



    Рисунок 3.2 — Алгоритм распознавания последовательности

    Распознавание элементов последовательности осуществляется четверками, т.е. необходимо обеспечить последовательную загрузку в узел элементов Y c номерами 0-3, 4- 7, 8-B, C-F для успешного распознавания последовательности. При осуществлении ввода значения, не соответствующего текущему ожидаемому элементу последовательности, необходимо повторить ввод всей четверки элементов заново.

    3.2 Описание автомата

    Сначала потребовалась таблица истинности. Она уже была построена в первом разделе и представлена в Таблице 1.2. Далее следовало представить структурную схему готового цифрового узла. С её помощью можно детально рассмотреть входы и выходы каждого отдельного модуля. Данная схема (Verilog RTL-модель, описывающая верхний уровень иерархии) представлена на Рисунке 3.3.



    Рисунок 3.3 — Структурная схема автомата

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

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

    Семисегментный индикатор, как говорит его название, состоит из семи элементов индикации (сегментов), включающихся и выключающихся по отдельности. Включая их в разных комбинациях, из них можно составить упрощённые изображения арабских цифр. В обычном светодиодном индикаторе используется девять выводов: один идёт к катодам (минусам) всех сегментов, и остальные восемь — к аноду каждого из сегментов, включая точку. Эта схема называется «схема с общим катодом», существуют также схемы с общим анодом, где имеется общий анод (плюс) и индивидуально подключенные катоды. Часто делают не один, а два общих вывода на разных концах корпуса — это упрощает разводку, не увеличивая габаритов.

    Для модуля обработчика сигнала катодов требовалось правильно соотнести отображаемую цифру с набором включённых и выключенных катодов. Каждый катод отвечает за свой светодиод, следовательно, нужно было правильно задать последовательность разрядов. Общая схема выводов семисегментного индикатора представлена на Рисунке 3.4.



    Рисунок 3.4 — Выводы семисегментного индикатора

    3.3 Содержание модулей

    Нужно было реализовать модуль, отвечающий за сброс. Данный модуль переводит весь цифровой узел в начальное состояние. Реализация представлена в Листинге 3.1.

    Листинг 3.1 — Модуль RST (RST.v)

    module RST(

    input clk,

    input cpu_reset,

    output rst

    );

    reg rst;

    always @(posedge clk, negedge cpu_reset)

    begin

    if (!cpu_reset) begin

    rst <= 1'b1;

    end

    else begin

    rst <= 1'b0;

    end

    end
    endmodule

    Главная часть цифрового узла — модуль конечного автомата. Его код представлен в Листинге 3.2.

    Листинг 3.2 — Основной модуль автомата (MAIN.v)

    module MAIN(

    input RST,

    input CLK,

    input BTN_C,

    input [3:0] NewV,

    output reg [31:0] CODE

    );

    reg [1:0] V_counter = 2'b00;

    reg [3:0] V;

    reg [3:0] V_index = 4'h0;

    reg [3:0] V_point = 4'h1;

    always @ (posedge CLK, posedge RST)

    begin

    if (RST) begin

    V_counter <= 2'b00;

    CODE <= 32'hxxxx1xxx;

    V_index <= 4'h1;

    V_point = 4'h1;

    end

    else if (BTN_C) begin

    CODE[19:16] <= CODE[23:20];

    CODE[23:20] <= CODE[27:24];

    CODE[27:24] <= CODE[31:28];

    CODE[31:28] <= NewV;

    if (NewV == CODE[15:12]) begin

    if (V_counter == 2'b11) begin

    CODE[15:0] <= 16'hxxxx;

    V_point <= V;

    end

    else begin

    CODE[3:0] <= CODE[7:4];

    CODE[7:4] <= CODE[11:8];

    CODE[11:8] <= CODE[15:12];

    end

    CODE[15:12] <= V;

    V_index <= V_index + 1'b1;

    V_counter <= V_counter + 1'b1;

    end

    else begin

    CODE[15:0] <= 16'hxxxx;

    V_index <= V_index - V_counter;

    CODE[15:12] <= V_point;

    V_counter <= 2'b00;

    end

    end

    end
    always @ (V_index)

    begin

    case(V_index)

    Продолжение Листинга 3.2

    4'h0: V <= 4'hD;

    4'h1: V <= 4'hC;

    4'h2: V <= 4'h8;

    4'h3: V <= 4'hD;

    4'h4: V <= 4'h4;

    4'h5: V <= 4'h9;

    4'h6: V <= 4'hA;

    4'h7: V <= 4'hE;

    4'h8: V <= 4'hF;

    4'h9: V <= 4'hD;

    4'hA: V <= 4'h2;

    4'hB: V <= 4'hD;

    4'hC: V <= 4'hA;

    4'hD: V <= 4'hE;

    4'hE: V <= 4'hE;

    4'hF: V <= 4'hA;

    default: V <= 4'hx;

    endcase

    end

    endmodule

    Также был реализован модуль, как раз отвечающий за обработку сигналов анодов, он представлен в Листинге 3.3.

    Листинг 3.3 — Модуль обработчика сигналов анодов (AN_DECODER.v)

    module AN_DECODER(

    input [2:0] CNT,

    output reg [7:0] AN,

    output reg [3:0] HEX_AN

    );

    always @ (CNT)

    case(CNT)

    3'h0: AN<=8'h7F;

    3'h1: AN<=8'hBF;

    3'h2: AN<=8'hDF;

    3'h3: AN<=8'hEF;

    3'h4: AN<=8'hF7;

    3'h5: AN<=8'hFB;

    3'h6: AN<=8'hFD;

    3'h7: AN<=8'hFE;

    endcase

    //------------------------------

    always @ (AN)

    case(AN)

    8'b01111111: HEX_AN<=4'h7;

    8'b10111111: HEX_AN<=4'h6;

    8'b11011111: HEX_AN<=4'h5;

    8'b11101111: HEX_AN<=4'h4;

    8'b11110111: HEX_AN<=4'h3;

    8'b11111011: HEX_AN<=4'h2;

    8'b11111101: HEX_AN<=4'h1;

    8'b11111110: HEX_AN<=4'h0;

    endcase

    //-------------------------------
    endmodule

    Разработанный модуль для управления катодами индикатора приведён в Листинге 3.4.

    Листинг 3.4 — Модуль обработчика сигналов катодов (CAT_DECODER.v)

    module CAT_DECODER(

    input [2:0] CNT,

    input [31:0] CODE,

    output reg [7:0] CAT,

    output reg [3:0] HEX_CAT

    );
    reg [3:0] I_CODE;
    always @ (CNT)

    case(CNT)

    3'h0: I_CODE <= CODE[3:0];

    3'h1: I_CODE <= CODE[7:4];

    3'h2: I_CODE <= CODE[11:8];

    3'h3: I_CODE <= CODE[15:12];

    3'h4: I_CODE <= CODE[19:16];

    3'h5: I_CODE <= CODE[23:20];

    3'h6: I_CODE <= CODE[27:24];

    3'h7: I_CODE <= CODE[31:28];

    default: I_CODE <= 4'bx;

    endcase
    always @ (I_CODE)

    case(I_CODE)

    4'h0: CAT <= 8'b11000000;

    4'h1: CAT <= 8'b11111001;

    4'h2: CAT <= 8'b10100100;

    4'h3: CAT <= 8'b10110000;

    4'h4: CAT <= 8'b10011001;

    4'h5: CAT <= 8'b10010010;

    4'h6: CAT <= 8'b10000010;

    4'h7: CAT <= 8'b11111000;

    4'h8: CAT <= 8'b10000000;

    4'h9: CAT <= 8'b10010000;

    4'hA: CAT <= 8'b10001000;

    4'hB: CAT <= 8'b10000011;

    4'hC: CAT <= 8'b11000110;

    4'hD: CAT <= 8'b10100001;

    4'hE: CAT <= 8'b10000110;

    4'hF: CAT <= 8'b10001110;

    default: CAT <= 8'b11111111;

    endcase
    //---------------------------------

    always @ (CAT)

    case(CAT)

    8'b11000000: HEX_CAT<=4'h0;

    8'b11111001: HEX_CAT<=4'h1;

    8'b10100100: HEX_CAT<=4'h2;

    8'b10110000: HEX_CAT<=4'h3;

    8'b10011001: HEX_CAT<=4'h4;

    8'b10010010: HEX_CAT<=4'h5;

    8'b10000010: HEX_CAT<=4'h6;

    8'b11111000: HEX_CAT<=4'h7;

    8'b10000000: HEX_CAT<=4'h8;

    8'b10010000: HEX_CAT<=4'h9;

    8'b10001000: HEX_CAT<=4'hA;

    Продолжение Листинга 3.4

    8'b10000011: HEX_CAT<=4'hB;

    8'b11000110: HEX_CAT<=4'hC;

    8'b10100001: HEX_CAT<=4'hD;

    8'b10000110: HEX_CAT<=4'hE;

    8'b10001110: HEX_CAT<=4'hF;

    8'b11111111: HEX_CAT<=4'hx;

    endcase

    //------------------------------------
    endmodule

    Остался модуль верхнего уровня, который отвечает за правильное соединение всех остальных модулей. Код представлен в Листинге 3.5.

    Листинг 3.5 — Модуль верхнего уровня (TOP.v)

    module TOP(

    input CLK,

    input CPU_RST,

    input BTN_C,

    input [3:0] SW,

    output [7:0] CAT,

    output [7:0] AN

    );

    wire line_RST;

    wire line_CE;

    wire BTN_CE;

    wire [2:0] line_CNT;

    wire [31:0] line_CODE;
    RST FB1(

    .clk(CLK),

    .cpu_reset(CPU_RST),

    .rst(line_RST)

    );
    CLOCK_DIVIDER FB2(

    .rst(line_RST),

    .clk(CLK),

    .CEO(line_CE)

    );
    FILTER FB3(

    .clk(CLK),

    .CE(line_CE),

    .BTN_IN(BTN_C),

    .rst(line_RST),

    .BTN_CEO(BTN_CE)

    );
    COUNTER FB4(

    .DISD_CE(line_CE),

    .RST(line_RST),

    .CLK(CLK),

    .CNT(line_CNT)

    );
    AN_DECODER FB5(

    .CNT(line_CNT),

    Продолжение Листинга 3.5

    .AN(AN)

    );
    MAIN FB6(

    .CLK(CLK),

    .RST(line_RST),

    .BTN_C(BTN_CE),

    .NewV(SW),

    .CODE(line_CODE)

    );
    CAT_DECODER FB7(

    .CNT(line_CNT),

    .CODE(line_CODE),

    .CAT(CAT)

    );

    endmodule
    1   2   3   4   5   6


    написать администратору сайта