Как устроена FPGA внутри: LUT, триггеры, матрица соединений

Заглядываем внутрь FPGA и разбираем кирпичики, из которых собирается любая схема.

LUT (Look-Up Table, таблица поиска) — крошечная память, которая по комбинации входов выдаёт заранее записанный бит; так FPGA реализует любую логическую функцию от нескольких входов.

FPGA — это регулярная решётка из одинаковых блоков, соединённых программируемыми проводами. Чтобы описывать схемы осмысленно, нужно понимать, из чего эти блоки состоят. Главных кирпичиков три: LUT (для комбинационной логики), триггер (для памяти на один бит) и программируемая матрица соединений (которая связывает всё это в нужную схему).

LUT — универсальный логический элемент

Самый хитрый кирпичик — LUT. Это не вентиль И или ИЛИ, а маленькая таблица истинности, записанная в память. LUT с N входами хранит 2^N бит: для каждой комбинации входов — один заранее заданный выход. Меняя содержимое таблицы, один и тот же LUT превращается то в И, то в ИЛИ, то в XOR, то в любую функцию от N переменных.

Покажем на Python, как 4-битная таблица задаёт логику. Например, LUT на 2 входа с содержимым [0,1,1,0] — это XOR:

# LUT на 2 входа: 4 ячейки памяти, индекс = (a,b) как 2-битное число
# содержимое [0,1,1,0] задаёт функцию XOR
lut = [0, 1, 1, 0]

print(" a b | out")
print("-----+----")
for a in (0, 1):
    for b in (0, 1):
        index = a * 2 + b      # склеиваем входы в адрес ячейки
        out = lut[index]       # просто читаем бит из таблицы
        print(f" {a} {b} |  {out}")

Вывод:

 a b | out
-----+----
 0 0 |  0
 0 1 |  1
 1 0 |  1
 1 1 |  0

Запишите в ту же таблицу [0,0,0,1] — получите И, [0,1,1,1] — ИЛИ. Вот почему LUT называют универсальным: одна структура реализует любую логику. Реальные FPGA используют LUT на 4–6 входов.

Триггер, логический блок и соединения

Рядом с каждым LUT стоит триггер (flip-flop) — элемент, способный «запомнить» один бит до следующего такта. LUT даёт мгновенную логику, триггер добавляет память во времени. Пара «LUT + триггер» — это логическая ячейка; несколько ячеек объединяют в логический блок (его называют CLB у Xilinx или LAB у Intel). Схематично:

      входы
        |
        v
   +---------+        +-----------+
   |   LUT   |------->|  триггер  |---> выход
   | (логика)|  опц.  | (память)  |
   +---------+        +-----------+
                          ^
                          |
                        clock

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

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

Если бы умножение строили из одних LUT, оно вышло бы громоздким и медленным. Поэтому в FPGA встроены готовые аппаратные блоки:

  • DSP-блоки — аппаратные умножители-накопители (умножить и прибавить за такт). Их много, и они ключевые для фильтров и нейросетей.
  • Block RAM (BRAM) — блоки встроенной памяти на килобиты, для буферов и таблиц.
  • Блоки тактирования (PLL/MMCM) — формируют и умножают тактовые частоты.
  • Блоки ввода-вывода (IOB) — связывают внутреннюю схему с ножками микросхемы.

Когда вы пишете в Verilog a * b, синтезатор не выкладывает умножитель из LUT, а подключает аппаратный DSP-блок. Понимание, что таких блоков конечное число, важно: проект может «не влезть» в FPGA не из-за нехватки LUT, а из-за того, что DSP-блоков или BRAM не хватило.

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

  • Путать LUT с вентилем. LUT — это память-таблица, а не фиксированный вентиль; его поведение задаётся содержимым.
  • Думать, что ресурс один. Кроме LUT есть триггеры, DSP, BRAM, тактовые ресурсы — проект упирается в самый дефицитный из них.
  • Игнорировать соединения. Часто схема не работает на нужной частоте не из-за логики, а из-за длинных маршрутов через матрицу соединений.

Итог

  • LUT — таблица поиска, реализующая любую логику от нескольких входов.
  • Триггер хранит бит; пара LUT+триггер образует логическую ячейку.
  • Матрица соединений программируемо связывает блоки и занимает много площади.
  • DSP, BRAM, PLL — специализированные блоки; их количество ограничено.
Проверьте себя
1. Что физически представляет собой LUT в FPGA?
AФиксированный вентиль И
BМаленькую память-таблицу, выдающую заранее записанный бит по комбинации входов
CАналоговый усилитель
DТактовый генератор
2. Сколько бит хранит LUT с N входами?
AN бит
B2^N бит
CN^2 бит
DВсегда 1 бит
3. Почему операцию умножения в FPGA обычно выполняет не набор LUT, а отдельный блок?
ALUT не умеют умножать в принципе
BВ FPGA есть аппаратные DSP-блоки — умножители, которые быстрее и компактнее набора LUT
CУмножение запрещено в Verilog
DDSP-блоки бесплатны и бесконечны