Практические проекты: ШИМ, бегущий огонёк, 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 + сдвиг + делитель (первый протокол).
- Все проекты собираются из базовых блоков курса; новой «магии» не нужно.