Практические проекты: ШИМ, бегущий огонёк, UART

Связываем изученное в конкретные проекты, которые собирает каждый начинающий FPGA-инженер.

ШИМ (PWM, широтно-импульсная модуляция) — способ задавать «среднюю мощность» цифровым сигналом: меняя долю времени, когда сигнал включён (скважность), управляют яркостью светодиода или скоростью мотора.

Теория оживает в проектах. Все «первые проекты» на FPGA собираются из уже знакомых вам кирпичиков: счётчиков, делителей, автоматов. Разберём четыре классических проекта — что в каждом устроено и какие приёмы он закрепляет. Это карта того, что вы уже умеете применить.

Бегущий огонёк (knight rider)

Самый первый проект: ряд светодиодов, по которому «бежит» зажжённая точка туда-обратно. Внутри — делитель частоты (чтобы глаз успевал видеть) и сдвиговый регистр или счётчик-указатель. Закрепляет: делитель частоты, регистры, сдвиги.

// фрагмент: сдвигаем зажжённый бит по 8 светодиодам
always @(posedge slow_clk) begin   // slow_clk от делителя
    if (dir == 0)
        leds <= leds << 1;          // сдвиг влево
    else
        leds <= leds >> 1;          // сдвиг вправо
end

ШИМ: управление яркостью и моторами

ШИМ — это счётчик и компаратор: счётчик бежит по кругу, а выход включён, пока счётчик меньше порога (duty). Чем выше порог, тем дольше сигнал включён, тем ярче светодиод. Это фундамент управления светом и моторами. Промоделируем ШИМ на Python, посчитав среднюю мощность для разной скважности:

PERIOD = 10        # период ШИМ в тактах
print("duty | сигнал по тактам      | средняя мощность")
print("-----+-----------------------+-----------------")
for duty in [2, 5, 8]:
    signal = "".join("1" if t < duty else "0" for t in range(PERIOD))
    power = 100 * duty // PERIOD
    print(f"  {duty}  | {signal} |      {power}%")

Вывод:

duty | сигнал по тактам      | средняя мощность
-----+-----------------------+-----------------
  2  | 1100000000 |      20%
  5  | 1111100000 |      50%
  8  | 1111111100 |      80%

Меняя duty от 0 до 10, мы плавно регулируем среднюю мощность от 0 до 100% — так одним цифровым выводом управляют аналоговой на вид яркостью. Закрепляет: счётчики, компараторы, параметры.

Светофор на FSM

Уже знакомый по разделу про автоматы проект: состояния RED/GREEN/YELLOW, переходы по таймеру (делителю), выходы на лампы. Добавив кнопку пешехода или ночной режим, получаем нетривиальный автомат. Закрепляет: FSM, делитель частоты, кодирование состояний.

UART-передатчик

Более серьёзный проект — передатчик UART (последовательный интерфейс, по которому FPGA «разговаривает» с компьютером). Внутри — автомат с состояниями: ожидание, старт-бит, 8 бит данных по очереди, стоп-бит. Скорость задаёт делитель (baud rate). Это первый «настоящий» протокол и отличная тренировка FSM + тайминга. Схема состояний:

[IDLE] --есть данные--> [START] --> [DATA x8] --> [STOP] --> [IDLE]
  линия=1              старт-бит=0   биты по одному  стоп-бит=1
                       (каждый бит держится 1/baud секунды)

Закрепляет: FSM, сдвиговый регистр, делитель частоты, тайминг. Освоив UART, легко перейти к SPI, I2C, а затем — к видеовыходу VGA и простому процессору.

Как работает под капотом: всё из знакомых блоков

Главный вывод: ни один из этих проектов не требует «новой магии». ШИМ — счётчик + компаратор. Светофор — FSM + делитель. UART — FSM + сдвиг + делитель. Освоив базовые блоки курса, вы уже способны собрать любой из них. Дальше масштаб растёт (контроллер памяти, видеоконтроллер, мягкий процессор RISC-V), но кирпичики те же.

Частые ошибки

  • Браться сразу за процессор. Начинайте с огонька и ШИМ; они дают быстрый видимый результат и закрепляют основы.
  • Тактировать ШИМ слишком медленно. Если частота ШИМ ниже ~1 кГц, светодиод заметно мерцает, а мотор дёргается.
  • Пропускать симуляцию UART. Ошибки тайминга бит почти невозможно отладить без осциллограмм — симулируйте.

Итог

  • Бегущий огонёк — делитель + сдвиг; первый видимый проект.
  • ШИМ — счётчик + компаратор; управляет яркостью и моторами через скважность.
  • Светофор — FSM + делитель; UART — FSM + сдвиг + делитель (первый протокол).
  • Все проекты собираются из базовых блоков курса; новой «магии» не нужно.
Проверьте себя
1. Как ШИМ (PWM) управляет яркостью светодиода?
AМеняет напряжение питания
BМеняет скважность — долю времени, когда сигнал включён, регулируя среднюю мощность
CМеняет тактовую частоту FPGA
DИспользует аналоговый ЦАП
2. Из каких базовых блоков состоит ШИМ-генератор?
AИз block RAM и PLL
BИз счётчика и компаратора: выход включён, пока счётчик меньше порога duty
CИз синхронизатора и FIFO
DИз одного триггера
3. Что лежит в основе UART-передатчика?
AКомбинационный мультиплексор
BКонечный автомат (FSM) с состояниями старт-бит, биты данных, стоп-бит и делитель для скорости
CТолько block RAM
DАналоговый фильтр