DocsTech
/
ЦОС
/

~ cd введение в fsm (конечные автоматы) в fpga verilog

Конечные автоматы (Finite State Machines, FSM) — это математическая модель, широко используемая в проектировании цифровых систем, в том числе на языке Verilog для FPGA (Field-Programmable Gate Array). FSM представляют собой один из основных способов управления последовательностями операций в цифровых системах и могут использоваться для создания сложных схем управления, алгоритмов или систем автоматизации. В этой статье мы разберем, что такое FSM, как они строятся, их преимущества и недостатки, и приведем пример реализации конечного автомата на Verilog.

Что такое FSM?

FSM — это модель, состоящая из набора состояний, переходов между этими состояниями и событий, которые инициируют эти переходы. В простейшем виде конечный автомат работает по принципу: система находится в одном из нескольких предопределённых состояний и переходит в другое состояние в зависимости от входных сигналов.

FSM состоит из:

  1. Набора состояний — различных положений системы.
  2. Переходов между состояниями — условные переходы между состояниями, зависящие от входных данных.
  3. Входных сигналов — управляющих условий, которые определяют, когда и куда будет осуществлён переход.
  4. Выходных сигналов — действия, выполняемые в каждом состоянии.

Примеры использования FSM включают системы управления лифтами, контроллеры памяти, процессоры и цифровые фильтры.

Принцип построения FSM

FSM можно разделить на два основных типа:

  1. Автомат Мура — выходная логика зависит только от текущего состояния.
  2. Автомат Мили — выходная логика зависит как от текущего состояния, так и от входных сигналов.

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

Построение FSM на Verilog проходит через несколько шагов:

Шаги построения FSM:

  1. Определение состояний:
    Первым шагом является определение всех возможных состояний системы. Состояния можно кодировать с помощью параметров, используя уникальные бинарные или символические коды. FSM может быть одноуровневым или иерархическим, в зависимости от сложности задачи.
  2. Определение переходов:
    Для каждого состояния определяется, как и при каких условиях система переходит в другие состояния. Это можно описать с помощью логики переходов, используя конструкции case
    , if ил
    else.
  3. Определение выходов:
    В каждом состоянии необходимо указать действия, которые система выполняет.
  4. Реализация на Verilog:
    На этом этапе FSM кодируется с использованием конструкций Verilog, таких как регистры, синхронизация по тактовым сигналам, операторы управления и логические выражения.

Компоненты FSM

FSM на Verilog состоит из следующих компонентов:

  1. Состояния — множество возможных состояний системы.
  2. Переходы — правила, определяющие, как и при каких условиях FSM будет перемещаться между состояниями.
  3. Входы — сигналы, которые контролируют переходы между состояниями.
  4. Выходы — сигналы, которые зависят от состояния или входов (в зависимости от типа автомата).
  5. Тактовый сигнал (Clock) — FSM синхронизируется по тактовому сигналу, который задаёт интервалы, когда система может менять состояние.

Преимущества и недостатки FSM

Преимущества:

Недостатки:

Пример реализации FSM на Verilog

Для работы с микросхемой FT245RL через FSM на Verilog мы будем использовать следующие сигналы:

  1. D[7:0] — 8-битная шина данных для передачи и приёма данных.
  2. RD# (Read) — сигнал для чтения данных (активный низкий).
  3. WR (Write) — сигнал для записи данных (активный низкий).
  4. RXF# (Receive FIFO Full) — сигнал, указывающий, что данные доступны для чтения (активный низкий, FIFO не пуст).
  5. TXE# (Transmit FIFO Empty) — сигнал, указывающий, что можно записывать данные (активный низкий, FIFO не полный).

Задачи модуля:

  1. Чтение данных, когда FIFO FT245RL не пусто.
  2. Запись данных, когда FIFO FT245RL не заполнено.
  3. Управление сигналами чтения и записи через FSM.

Принцип работы FSM:

FSM будет состоять из следующих состояний:

  1. IDLE — Ожидание доступности данных для чтения или возможности записи.
  2. CHECK_RXF — Проверка, можно ли читать данные.
  3. READ_DATA — Чтение данных.
  4. CHECK_TXE — Проверка, можно ли записать данные.
  5. WRITE_DATA — Запись данных.
  6. DONE — Завершение операции чтения или записи.
Пример реализации FSM на Verilog:
...
Копировать
module ft245_fsm(
    input clk,                // Системный тактовый сигнал
    input rst_n,              // Сброс (активный низкий)
    input rxf_n,              // RXF# сигнал (FIFO не пуст)
    input txe_n,              // TXE# сигнал (FIFO не заполнен)
    input [7:0] data_in,      // 8-битная шина данных FT245RL для чтения
    output reg [7:0] data_out,// Данные для записи в FT245RL
    output reg rd_n,          // RD# сигнал для чтения данных (активный низкий)
    output reg wr_n,          // WR сигнал для записи данных (активный низкий)
    output reg [7:0] read_data// Принятые данные
);

    // Определение состояний FSM
    reg [2:0] IDLE = 3'b000;         // Ожидание данных для чтения или записи
    reg [2:0] CHECK_RXF = 3'b001;    // Проверка, можно ли читать
    reg [2:0] READ_DATA = 3'b010;    // Чтение данных
    reg [2:0] CHECK_TXE = 3'b011;    // Проверка, можно ли записать данные
    reg [2:0] WRITE_DATA = 3'b100;   // Запись данных
    reg [2:0] DONE = 3'b101;         // Завершение операции

    // Основной блок FSM
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) 
            current_state <= IDLE; // При сбросе переходим в начальное состояние
        else 
            current_state <= next_state; // Переход в следующее состояние
    end

    // Логика переходов состояний
    always @(*) begin
        case (current_state)
            IDLE: begin
                if (!rxf_n)           // Если FIFO не пуст, готово для чтения
                    next_state = CHECK_RXF;
                else if (!txe_n)      // Если FIFO не заполнено, можно писать
                    next_state = CHECK_TXE;
                else
                    next_state = IDLE; // Ожидание
            end

            CHECK_RXF: begin
                next_state = READ_DATA; // Переход к чтению данных
            end

            READ_DATA: begin
                next_state = DONE;      // Переход к завершению после чтения
            end

            CHECK_TXE: begin
                next_state = WRITE_DATA; // Переход к записи данных
            end

            WRITE_DATA: begin
                next_state = DONE;       // Переход к завершению после записи
            end

            DONE: begin
                next_state = IDLE;      // Возвращаемся в состояние ожидания
            end

            default: next_state = IDLE;
        endcase
    end

    // Логика управления выходами
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            rd_n <= 1'b1;           // RD# неактивен (активный низкий)
            wr_n <= 1'b1;           // WR неактивен
            read_data <= 8'b0;      // Обнуляем принятые данные
            data_out <= 8'b0;       // Обнуляем выход данных
        end else begin
            case (current_state)
                IDLE: begin
                    rd_n <= 1'b1;   // RD# неактивен
                    wr_n <= 1'b1;   // WR неактивен
                end

                CHECK_RXF: begin
                    rd_n <= 1'b0;   // Активируем RD# для чтения данных
                end

                READ_DATA: begin
                    read_data <= data_in; // Чтение данных с шины
                    rd_n <= 1'b1;        // Отключаем RD# после чтения
                end

                CHECK_TXE: begin
                    wr_n <= 1'b0;    // Активируем WR для записи данных
                    data_out <= 8'hAA; // Пример данных для записи
                end

                WRITE_DATA: begin
                    wr_n <= 1'b1;    // Отключаем WR после записи данных
                end

                DONE: begin
                    rd_n <= 1'b1;    // RD# неактивен
                    wr_n <= 1'b1;    // WR неактивен
                end
            endcase
        end
    end
endmodule

Описание работы FSM:

  1. IDLE: FSM находится в ожидании, пока FIFO не станет доступным для чтения или записи. Если сигнал RXF# активен (FIFO не пуст), FSM переходит в состояние CHECK_RXF, где начинается процесс чтения. Если сигнал TXE# активен (FIFO не заполнен), FSM переходит в состояние CHECK_TXE, где начинается процесс записи.
  2. CHECK_RXF: В этом состоянии активируется сигнал RD#, и FSM подготавливается для чтения данных. Данные принимаются через шину D[7:0].
  3. READ_DATA: Прочитанные данные сохраняются в регистре read_data, а сигнал RD# отключается.
  4. CHECK_TXE: В этом состоянии активируется сигнал WR, и данные передаются через шину D[7:0]. В примере записываются данные 8'hAA.
  5. WRITE_DATA: Данные записываются в FT245RL через шину, и сигнал WR отключается.
  6. DONE: Завершение операции, FSM возвращается в исходное состояние IDLE для ожидания следующего цикла.

Этот модуль управляет процессом чтения и записи данных через микросхему FT245RL с помощью FSM, обрабатывая сигналы RXF# и TXE# для определения, когда можно читать или писать данные.

Заключение

FSM являются мощным инструментом для проектирования цифровых систем управления в FPGA, обеспечивая ясную структуру состояний и переходов. Их простота и гибкость позволяют реализовать различные алгоритмы управления, хотя с увеличением сложности системы могут возникнуть ограничения в удобстве проектирования. Знание конечных автоматов и их реализация на языке Verilog является важным навыком для разработчиков цифровых систем.

FAQ

1. Чем отличается автомат Мура от Мили?
Автомат Мура управляет выходами только на основе текущего состояния, тогда как автомат Мили учитывает как текущее состояние, так и входные сигналы для определения выходов.

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

3. Какой язык программирования используется для реализации FSM в FPGA?
Одним из самых популярных языков для реализации FSM является Verilog, также часто используется язык VHDL.

4. Что делать, если моя система слишком сложная для FSM?
В таких случаях можно рассмотреть использование иерархических FSM или других подходов, таких как микропроцессоры или программируемые логические контроллеры (PLC).

5. Каким образом FSM применяется в реальных системах?
FSM используется в контроллерах памяти, процессорах, цифровых фильтрах, автоматизации промышленных процессов и в других системах, где требуется управление последовательностями операций.

Главная
Курсы
Вебинары
Шифрование AES: Что такое, как работает и почему это лучший выбор для безопасности данных
Введение в FSM (Конечные Автоматы) в FPGA Verilog
Latency в ЦОС: как её минимизировать
8 наиболее используемых Контрольных Сумм
Помехоустойчивое кодирование: описание, типы, применение
Высокочастотный цифровой фильтр в последовательной форме на ПЛИС
Амплитудная модуляция(AM): Что это такое?
Балансный Фазовый Детектор на Verilog
Фазовый детектор: описание, схемы и принцип работы
БИХ (Рекурсивный) Фильтр: Что это такое?
КИХ фильтр: описание и примеры на ПЛИС, stm32 и esp32
Фазовый накопитель: применение в ПЛИС и STM32 и ESP32
Цифровая Обработка Сигналов: введение
Закрыть