Архитектура ПЛИС. Часть 1. Логический элемент
Шауэрман Александр А. shamrel@yandex.ru
Для многих начинающих разработчиков ПЛИС представляется неким волшебным черным ящиком, который по мановению компилятора превращает исходный код в реально действующую схему. И кажется думать не нужно, что там внутри, пиши и пиши себе абстрактный код, особенно, если используется высокоуровневый язык, такой как Verilog. Но первое отрезвление приходит, когда выясняется, что в том же Veriloge есть синтезируемое и не синтезируемое подмножество. Оказывается, не все возможности языка могут быть реализованы в железе. Второе отрезвление наступает, когда выясняется, что комбинация некоторых синтезируемых по отдельности выражений отказывается работать вместе. Я помню свою по-детски наивную обиду, когда выяснилось, что одному регистру нельзя присвоить значение в различных блоках always. Или когда не удалось заставить always работать от положительного и от отрицательного фронта одного тактового сигнала. Хотя и то, и другое языком не запрещено и многие симуляторы запустят такой код. Потому рано или поздно разработчик должен отказаться от концепции черного ящика и изучить аппаратные возможности и структуру ПЛИС.
Каждое семейство ПЛИС обладает своими особенностями архитектуры, однако нас в первую очередь будет интересовать семейство Cyclone IV, так как на нем выполнен отладочная плата LESO2.
В ПЛИС для конфигурации используется оперативная память CRAM (Configuration RAM). Эта память распределена по всему кристаллу, значения, записанные в нее, управляют внутренним коммутационным полем, определяя структуру синтезируемого цифрового устройства. Как правило, в ПЛИС архитектуры FPGA эта память энергозависимая и при подаче питания на устройство требуется загрузить в нее значения из какого-либо внешнего (по отношению к кристаллу ПЛИС) носителя, часто для этих целей используется микросхема ПЗУ (Постоянное Запоминающее Устройство), либо микроконтроллер, а в случае стенда LESO2, загрузка осуществляется из компьютера.
Одной из важнейших характеристик ПЛИС является ее логическая емкость. Емкость определяет насколько сложные цифровые устройства можно синтезировать. Другими словами, логическая емкость показывает сколько всего поместится в кристалле. Если вам уже доводилось компилировать в Quartus II проект для ПЛИС, то должны были обратить внимание на итоговый отчет, где указывается какие ресурсы и в каком количестве использованы в проекте, а также указывается процентное соотношение от максимального. Основной ресурс ПЛИС – это логические элементы (Logic Elements). В ПЛИС EP4CE6E22C8, а именно такая использована в учебном стенде, таких элементов 6272. Это много или мало? Для того, чтобы ответить на это вопрос, следует рассмотреть, что же из себя представляет этот логический элемент.
Базовый логический элемент
Из булевой алгебры известно, что используя некий элементный базис, например элемент И-НЕ или ИЛИ-НЕ, можно реализовать любую логическую функцию. Однако использование лишь одного типа элемента не всегда оправдано технически, при синтезе сложных устройств большое количество элементов увеличит время прохождения сигнала и тем самым снизит быстродействие. Поэтому в ПЛИС структуры FPGA в качестве простейшего логического элемента используют более сложную структуру, представляющей собой соединение программируемого комбинационного устройства и D-триггера. На рисунке 1 показана упрощенная структура такого элемента.
Рисунок 1 – Обобщенная структура логического элемента (LE) ПЛИС
Ячейка имеет три логических входа DATAA, DATAB и DATAC, вход тактовых импульсов CLK и один выход LEOUT. В случае если от ячейки требуется работа в качестве только комбинационного устройства, то выходной мультиплексор коммутирует выход элемента LUT на выход всей ячейки, если выход должен быть регистровым, то сигнал с LUT защелкивается по сигналу синхронизации в D-триггер, выход которого через мультиплексор соединяется с LEOUT. Управляющий вход мультиплексора (на рисунке не показан) подключен к соответствующему биту конфигурационной памяти CRAM.
Если ни у кого не вызывает вопросов как работает триггер и мультиплексор, то с элементом, обозначенным на схеме как LUT, все несколько сложнее. Аббревиатура LUT расшифровывается как Look-Up Table или просто Lookup Table, что дословно можно перевести как "справочная таблица" или "таблица поиска". LUT – это больше, чем таблица, LUT – это скорее метод реализации функции, в котором непосредственное вычисление заменяется поиском по таблице готовых решений. Применительно к ПЛИС это позволяет реализовать любую логическую функцию в виде памяти SRAM, где адрес – это аргумент, а содержимое ячейки – значение. Таким образом, для того, чтобы описать логическую функцию трех переменных (в приведенном примере именно три переменные: DATAA, DATAB и DATAC) достаточно памяти на 8 ячеек. Требуемая таблица истинности хранится в виде маски (LUT-mask) в соответствущей ячейке CRAM. С помощью мультиплексоров выбирается нужное значение. Мультиплексорами управляют сигналы входных портов для построения k-входовой LUT (k-LUT), которая реализует любую логическую функцию из k переменных, требуется 2k бит SRAM и 2k-1 мультиплексоров. На рисунке ниже показана трехвходовая LUT.
Рисунок 2 – Устройство LUT
При таком подходе можно достаточно точно спрогнозировать время прохождения сигнала и оно не будет зависеть от реализуемой логической функции. Эта важная особенность делает возможным временной анализ схемы.
Хорошо! Используя логический элемент, показанный на рисунке 1, можно получить любую логическую функцию трех переменных и ее регистровый вариант. А как быть, если нам понадобится реализовать какой-либо триггер, отличный от D-триггера? Для реализации некоторых типов достаточно имеющегося комбинационного устройства (LUT) на входе D-триггера, но для реализации всех известных триггеров нам все же придется внести некоторые изменения в базовую схему. Во-первых, необходимо ввести обратную связь: для этого с выхода D-триггера подадим сигнал на один из входов LUT. Для того, чтобы достигнутый ранее функционал не пострадал, мы не имеем право занимать уже имеющиеся входа, заменим LUT на 4-х входовый. Во-вторых, увеличим функциональность самого D-триггера, добавим дополнительные линии управления: вход разрешения ENA (от английского "Enable" – "Включить") и вход асинхронного сброса ACLR (от английского "Asynchronous Clear" – "Асинхронная Очистка"). В результате получим схему пригодную для синтеза любых триггеров:
Рисунок 3 – Структура логического элемента (LE) с обратной связью
Существует особый широко распространенный класс логических функций, который подразумевает наличие двух выводов. Речь идет о сумматорах. На вход полного двоичного сумматора поступает два операнда и флаг переноса из младшего разряда, а на выходе сумма и перенос в следующий двоичный разряд. Так как арифметические задачи типичны для ПЛИС, для работы с переносом в базовом логическом элементе предусмотрен специальный канал.
Рисунок 4 – Структура логического элемента (LE) с каналом переноса
Фактически для переноса требуется ввести дополнительную LUT, как показано на рисунке 4, но для простоты восприятия комбинацию LUT будем рассматривать как один целый модуль.
Используя канал переноса, легко объединить ячейки для получения многоразрядного сумматора. На рисунке 5 показана схема 4-разрядного сумматора с последовательным переносом, построенная на четырех базовых логических элементах.
Рисунок 5 – Четырехразрядный сумматор
При разработке базовой логической ячейки решались две задачи: во-первых, синтезируемые устройства должны обладать максимальным быстродействием, во-вторых, использование ресурсов должно быть как можно более полным. В предыдущем примере, если требуется работа сумматора исключительно как комбинационной схемы, выходные мультиплексоры сигнал возьмут с выходов LUT, а вся цепочка триггеров окажется неиспользованной. В противоположность этому, при синтезе последовательного или параллельного регистра, все LUT будут по сути выполнять функцию проводника: соединять вход LE с входом D-триггера. Небольшое дополнение к схеме, даст возможность при необходимости использовать комбинационное устройство и триггер элемента раздельно для синтеза независимых модулей. Мультиплексор на входе триггера позволит выбирать источник сигнала: либо с входа DATAC, либо с выхода LUT. Кроме того, появляется возможность организовать дополнительный канал соединения триггеров соседних LE для увеличения быстродействия при построении последовательных регистров. На рисунке 6 показана схема получившегося логического элемента. Вход REGIN и выход REGOUT образуют выделенный канал для соединения триггеров, вход SLOAD (от английского "Synchronous Loading" – "Синхронная загрузка") управляет выбором источника сигнала для входа триггера.
Рисунок 6 – Структура логического элемента (LE) с возможностью разделения LUT и триггера
Базовый логический ПЛИС Cyclone IV
Рассмотренный элемент LE в том или ином виде присутствует в различных семействах ПЛИС, в нем может быть увеличено количество входов и сложность LUT, добавлены дополнительные соединения внутри LE и порты для интеграции в глобальную коммутационную сеть ПЛИС. Так, например, в топовом семействе Stratix IV в один элемент входит две шестивходовые LUT, два выделенных полных сумматора и четыре триггера! Однако, с практической точки зрения, для эффективной работы со стендом LESO2 нам целесообразно рассмотреть более подробно реализацию LE в семействах Cyclone, в частности в Cyclone IV.
На рисунке 7 показана схема логического элемента ПЛИС Cyclone IV.
Рисунок 7 – Логический элемента (LE) Cyclone IV
Также, как и в базовом логическом элементе, каждый триггер имеет вход данных, вход тактовых импульсов CLK, вход разрешения ENA и вход асинхронного сброса (очистки) ACLR. Добавился сигнал синхронной очистки SCLR (от английского "Synchronous Clear" – "Асинхронная Очистка"): если на этом входе появится логическая единица, то следующим тактовым импульсом в триггер будет записал логический ноль. Все это позволяет настроить программируемый триггер каждой LE на работу в режиме D, T, JK или RS триггера.
Комбинационное устройство по сравнению с базовой схемой получило некоторое усложнение. На входе C LUT мультиплексор выбирает источник сигнала, благодаря чему LUT может реализовывать логическую функцию четырех переменных, кроме того, в качестве переменной может быть использован флаг переноса или выход собственного триггера.
В Cyclone IV LUT может работать в двух режимах: нормальном и арифметическом. Quartus II при компиляции автоматически выберет оптимальный режим для реализации требуемой функции. Нормальный режим предназначен для реализации основной логики и различных комбинационных функций. В этом режиме четыре входа LE (DATAA, DATAB, DATAC, DATAD) поступают на четыре входа LUT. Компилятор автоматически выбирает вход переноса CIN, вход DATAC или выход триггера (цепь обратной связи) в качестве одного из входов LUT. Арифметический режим подходит для синтеза сумматоров, счетчиков, аккумуляторов и компараторов (цепей сравнения). В этом режиме LUT представляет собой полный одноразрядный сумматор, включающий обработчик логики флага переполнения. Компилятор сам создает цепи переноса во время синтеза многоразрадных арифметических устройств.
Можно обратить внимание, что на рисунке логического элемента Cyclone IV отсутствует выходной мультиплексор, на самом деле он есть и не один. Но для того, чтобы понять логику их работы, нужно рассмотреть LE в контексте общей архитектуры ПЛИС.
Логические элементы LE объединяются в логические блоки LAB (Logic array blocks). В Cyclone IV каждый LAB содержит:
- 16 логических ячеек;
- сигналы управления LAB;
- цепи флага переноса LE;
- цепи каскадного объединения регистров;
- цепи локальных соединений.
Цепи локальных соединений передают сигналы между ячейками LE в одном LAB. Цепи объединения регистров соединяют выход регистра одного LE с входами регистров прилегающих ячеек LE. Компилятор Quartus II размещает связанную логику в LAB или в соседних LAB, позволяя использовать локальные цепи связи и связи регистров для увеличения производительности и эффективности размещения.
На цепи локальных соединений поступают сигналы со строк и столбцов глобального коммуникационного поля и с выходов ячеек LE, принадлежащих этому же блоку LAB. Соседние логические блоки, блок генератора с фазовой автоподстройкой частоты (PLL), ячейки памяти M9K RAM, встроенные умножители, расположенные с правой или левой стороны через специальные соединители, могут быть напрямую подключены к цепям локальных соединений LAB. Таким образом, любая ячейка LE может иметь соединение с шестнадшатью LE из своего блока (включая саму себя) и тридцатью двумя LE из LAB, расположенных слева или справа. Всего до 48-ми соединений! Такие непосредственные прямые соединения минимизируют использование глобальных маршрутов, обеспечивают большую гибкость при синтезе схемы и увеличивают общее быстродействие.
На рисунке 8 показана интеграция блока LAB в глобальную коммуникационную сеть ПЛИС.
Рисунок 8 – Структура соединений LAB в коммутационном поле ПЛИС
Каждый LE имеет три выхода, которые обеспечивают соединение с коммутационным полем ПЛИС. Эти выходы поступают на строки и столбцы глобальных соединительных трасс и на маршруты локальных соединений. Как и в базовом логическом элементе, LUT или триггер могут независимо управлять этими выходами.
Для того, чтобы можно было управлять всеми ячейками LE в пределах одного LAB одновременно, в логический блок встроена специальная логика и выделены особые линии – каналы управления. По таким каналам распространяются широковещательные (в пределах одного LAB) сигналы управления. Архитектура позволяет одновременно использовать до восьми управляющих сигналов:
- два тактовых сигнала (labclk1 и labclk2);
- два сигнала разрешения (labclkena1 и labclkena2);
- два сигнала асинхронного сброса (labclr1 и labclr2);
- сигнал синхронного сброса/очистки (synclr);
- сигнал синхронной загрузки (syncload).
Сигналы синхронной загрузки и сброса удобно использовать для синтеза различных счетчиков и регистров. Эти сигналы оказывают воздействие на все триггеры LE в пределах одного LAB.
На рисунке 9 показано подключение управляющих сигналов LAB и цепей локальных соединений к логической ячейке. Выводы LE соответствуют рисунку 7.
Рисунок 9 – Структура взаимодействия LE с сигналами управления
Каждый LAB имеет два тактовых сигнала и два сигнала разрешения. На уровне логического элемента выбирается какой сигнал будет подан на триггер, но тактовый сигнал связан с сигналом разрешения. Поэтому, хотя для любого LE в конкретной LAB можно выбрать какой тактовый сигнал использовать: labclk1 или labclk2, вместе с ним должен использоваться соответствующий сигнал разрешения. Например, если используется labclk1, вместе с ним будет использоваться только labcken1. Если LAB использует оба фронта (нарастающий и падающий) тактового сигнала, то будут задействованы оба канала тактирования, при этом логика выбора усложнится.
Chip Planer
После компиляции в окне Flow Summary можно посмотреть, какие ресурсы были использованы. После небольшого экскурса в архитектуру ПЛИС становился понятно, что значит Total logic elements и почему Total combinational function вынесено отдельной графой. Безусловно информация полезная, но для того, чтобы держать руку на пульсе этого явно недостаточно.
Рисунок 10 – Отчет компиляции
Для визуального контроля используемых ресурсов в Quartus II применяется утилита Chip Planer. Она показывает расположение и использование элементарных блоков в общей архитектуре целевой ПЛИС. Запустить Chip Planer можно из среды Quartus: меню Tools -> Chip Planer. На карте кристалла (рисунок 11) показаны все ресурсы ПЛИС: LE, объединенные в LAB, аппаратные умножители (DSP block), ячейки памяти, буферы ввода вывода, генераторы PLL. Цветом показана степень использования: светлым – неиспользуемые блоки, темным – максимально загруженные. Если увеличить масштаб (соответствующий инструмент на панел или ctrl+колесико мышки), то доступна детализация на уровне LE, здесь синим показан LUT, темно красным – триггер.
Большую детализацию можно получить если на панели Layers Settings сменить Basic на Detailed. В этом режиме при приближении видны локальные и глобальные цепи соединений, глобальные линии управления и управляющие сигналы LAB.
Рисунок 11 – Карта ресурсов ПЛИС
Если в LE выделить LUT или триггер, то на панели Node Properties можно увидеть схему LE и описание свойств и режимов работы. Двойной клик мыши по LUT или триггеру запустит в новом окне инструмент Resource Property Editor, в котором можно исследовать соединения внутри логического элемента. Синим выделены используемые цепи.
Рисунок 12 – Логический элемент в Resource Property Editor
Вместо заключения
Это далеко не полное описание архитектуры ПЛИС, за кадром остались такие важнейшие элементы как DSP блоки (умножители), блоки оперативной памяти, генератор PLL, буферы ввода-вывода, в последующих статьях цикла я постараюсь уделить им должное внимание. Однако следующий материал будет посвящен применению знаний о структуре логического элемента LE и об их объединении при проектировании простейших цифровых устройств.
Вторая статья цикла: Архитектура ПЛИС. Часть 2. Мультиплексор