Формат данных
В статье пойдёт речь о числах в формате с плавающей запятой и о реализации специализированного формата FP23 (от англ. Floating Point) на ПЛИС фирмы Xilinx. Числа с плавающей запятой активно используются в современных сигнальных процессорах (DSP), применяются практически во всех видеокартах и процессорах общего назначения и даже в ПЛИС. В соответствии со стандартом IEEE 754, они представляются в виде совокупности экспоненты (показателя степени), мантиссы и знака числа. Числа в стандарте IEEE 754 имеют 32 бита (float) полезных данных. С целью однозначности, числа с плавающей запятой записываются в нормальной форме или приводятся к нормализованному виду после любых математических операций и логических преобразований над ними. Диапазон возможных значений и точность представления чисел зависит от количества бит для мантиссы и экспоненты. Для стандартного float характерна фиксированная относительная точность и переменная абсолютная точность. Основные преимущества и недостатки чисел в формате с плавающей запятой по сравнению с числами с фиксированной запятой:
- Достоинства:
- обеспечивается очень широкий диапазон возможных значений;
- достигается высокая точность вычислений.
- Недостатки:
- округление очень больших чисел до возможных из сетки значений;
- потеря точности при суммировании чисел, отличных друг от друга на несколько порядков;
- сложность конкретной реализации и применения на ПЛИС.
Так или иначе, для современных ПЛИС разработка собственного формата чисел с плавающей запятой и выбранной мантиссой и экспонентой не составляет большого труда. Для продукции ведущих производителей (Xilinx и Altera) существуют готовые программные IP-ядра, реализующие float по стандарту. Помимо этого, для Altera в последних семействах Arria 10 представлены аппаратные IP-ядра, реализующие формат IEEE 754 на встроенных DSP-блоках.
Элементная база
Основная элементная база для выполнения математических операций и задач ЦОС – передовые семейства кристаллов ПЛИС. По сравнению с Xilinx, Altera в области использования формата с плавающей запятой ушла далеко вперёд. Для кристаллов Altera типа Arria 10 и Stratix 10 имеются жёсткие ядра вычислителей в формате с плавающей запятой внутри ПЛИС. В связи с этим становится актуальной задача по разработке быстрого формата данных с плавающей запятой на кристаллах ПЛИС фирмы Xilinx, которые не содержат жёстких блоков вычислителей c плавающей запятой.
Основные ресурсы современных кристаллов ПЛИС – это блоки конфигурационной логики и встроенной памяти. Но первоочередной практический интерес представляют универсальные блоки цифровой обработки и математики – DSP48E1 (для ПЛИС Xilinx серии Virtex 6 и 7 семейства) и DSP48E2 (для ПЛИС семейства Xilinx UltraScale). Эти блоки позволяют выполнять функции сложения и вычитания чисел, сдвига и переноса, быстродействующего умножения, перемножения с накоплением (MACC – Multiply Accumulate), поиска контрольной суммы и т.д. На ячейках DSP48 в современных ПЛИС выполняется множество задач: разработка СIC- и FIR-фильтров для классических задач радиотехники, скоростное вычисление FFT/IFFT для создания цифровых анализаторов спектра и устройств быстрой свёртки, реализация цифровых синтезаторов частоты (DDS и CORDIC), создание различных форматов представления данных и набора базовых операций для них.
Вторым основным компонентом ПЛИС является блочная память. Для ПЛИС Xilinx это ячейки RAMB36E1 (или RAMB18E1) – элементы двухпортовой памяти, реализованные внутри кристаллов ПЛИС в виде столбцов идентичных блоков. Количество столбцов встроенной памяти и их длина зависят от объёма кристалла. Максимальный объём блока памяти составляет 36 Кбит без использования каскадирования, при этом он может быть сконфигурирован как два независимых блока по 18 Кбит каждый. Блочная память может быть использована с шириной шины данных от 1 до 72 разрядов для типовых задач, а ширина шины адреса программируема. При отсутствии свободных ресурсов блочной памяти ПЛИС можно задействовать распределённую память в специальных конфигурационных ячейках SLICEM. Для ПЛИС Ultrascale объём распределённой памяти достигает 512 бит с однобитной шиной данных и возможностью реконфигурации глубины и разрядности шины.
Постановка задачи
С учётом перечисленных особенностей для реализации цифровой части задача формируется следующим образом. Пусть разрядность данных, поступающих в кристалл ПЛИС с микросхем АЦП, равна 16 бит. Положим, что адекватная скорость обработки данных, которая может считаться «высокой» в современных ПЛИС, – порядка 200–300 МГц. Для современных высокоскоростных систем сбора и обработки информации это типовые значения разрядности данных и тактовых частот. В качестве ПЛИС выбрана микросхема 6 или 7 серии, например, Kintex-7. Задача состоит в переводе 16-разрядного знакового целого числа FIX16 в специализированный формат с плавающей запятой FP23 и обратно, обеспечивая при этом максимальную скорость обработки внутри ПЛИС при минимальных затратах ресурсов кристалла. Кроме того, необходимо обозначить и реализовать набор базовых математических операций – сложение, вычитание и умножение.
Реализация формата данных с плавающей запятой
Число FP23 – это особый формат представления данных с плавающей запятой. В отличие от стандарта IEEE 754, длина информационного слова в формате FP23 не 32 бита, а всего 23 бита и один скрытый бит мантиссы. Данная формула в упрощённом виде отражает представление числа A в формате FP23:
А = (–1)SING(A) × 2exp(A–32) × MAN(A).
Мантисса (mantissa) в формате FP23 – это 17-битное положительное число. Она всегда отображается в нормализованном виде в результате всех преобразований, то есть самый старший бит мантиссы для ненулевого числа всегда равен 1. Для экономии ресурсов кристалла и упрощения записи 17-й бит мантиссы никогда не отображается в упакованном результирующем 23-битном слове (см. рис. 1).

Поэтому при вычислении математических операций и переводе из одного формата в другой необходимо помнить, что мантисса нормализована, и к 16-разрядному ненулевому числу необходимо прибавить значение 216 = 65536. Экспонента или показатель (exponent) в формате FP23 – это 6-битное положительное число, определяющее, на какую величину умножается мантисса. Для формата FP23 с 16-битной мантиссой достаточно экспоненты с шириной данных в 5 бит, но в практических целях введён дополнительный шестой бит для задач, где требуется накопление большого массива данных. Под знак выделен оставшийся один бит, причём нулевое значение бита соответствует положительным числам, а единичное значение определяет отрицательные числа. Для нулевой экспоненты значение знака не важно и отражает число +0 или –0. Таким образом, число A в формате FP23 описывается тремя битовыми полями: «экспонентой» (EXP(A)), «знаком» (SIGN(A)) и «мантиссой» (MAN(A)).
Итак, первый этап при разработке формата данных с плавающей запятой на ПЛИС состоит в переводе знакового целого числа фиксированной разрядности в формат с плавающей запятой FP23, обеспечивая при этом максимальную скорость обработки внутри ПЛИС. Второй этап заключается в обратном преобразовании чисел из формата FP23 в формат с фиксированной запятой с возможностью масштабирования выходных данных под определённый коэффициент деления. И наконец, на третьем этапе для полноценного использования всех преимуществ формата FP23 необходимо реализовать математические операции – сложение, вычитание и умножение.
В таблице 1 приведены разрядность данных, диапазон возможных значений мантиссы и экспоненты и т.д.

Почему разрядность данных в формате FP23 именно 23 бита? Ответ складывается из нескольких составляющих. Во-первых, один бит используется для знака и 15 оставшихся битов – для целой части, поэтому мантисса и знак занимают, как минимум, 16 битов. Для экспоненты, с учётом смещения в формуле, необходимо минимум 5 битов. Чем больше битов отводится под экспоненту, тем больше результат (расширяется диапазон возможных значений), но при фиксированной разрядности мантиссы точность для больших чисел падает. Пусть экспонента имеет 6 разрядов, а мантисса представлена как 16-разрядное число, на знак отводится 1 разряд. Для умножения и сложения мантисс используется узел DSP48, минимальная разрядность одного из входов которого равна 18 битам, а с учётом беззнаковых чисел – 17 битов. Следовательно, используя один блок DSP48, невозможно совершать арифметические действия над мантиссой шире 17 битов при минимальных затратах ресурсов ПЛИС.
Кроме того, значение 23 выбрано не случайно, так как в дальнейшем в задачах цифровой обработки для хранения вектора комплексных значений потребуется память ПЛИС. Пара чисел, вещественное и мнимое, без отображения скрытого бита имеет суммарную разрядность, равную 46, а с учётом флага переполнения – 48 битов, что по ширине данных укладывается ровно в три блока памяти RAMB18E1, либо в один блок RAMB36E1 и один блок RAMB18E1. Также для пары значений можно использовать дополнительные функции блока DSP48E1 – быстрое сравнение двух чисел, проверка на чётность и быстрое суммирование в режиме SIMD.
Таким образом, для представления чисел в формате FP23 используется именно 23 бита. Если использовать скрытый бит мантиссы, который равен 1 при ненулевых значениях или 0 при нулевых значениях двоичного числа, то разрядность равна 24. Дополнительные особенности формата FP23, отличные от классического IEEE 754 floating:
- отсутствуют специализированные команды NaN, а также положительная и отрицательная бесконечность;
- отсутствуют денормализованные числа (всегда нормализованы);
- флаги переполнения (overflow) и исчезновения числа (underflow) реализованы в виде отдельных сигналов, а не специализированных команд числа, либо вообще не используются;
- единица представляется как EXP(A) = 16, SIGN(A) = 0, MANT(A) = 0;
- дробные числа меньше нуля принимают значения экспоненты EXP(A) = [0; 15].
Преобразование FIX16 в FP23
Для преобразования данных из целочисленного знакового типа FIX16 в формат FP23 необходимо использовать конфигурационную логику кристалла ПЛИС и встроенные узлы умножения DSP48E1. На рисунке 2 изображена структурная схема преобразования данных в формат FP23.

Максимальная разрядность множителей блоков DSP48E1 – 25 и 18 соответственно, где старший бит – знаковый. Для перемножения чисел без учёта знака в модуле DSP48E1 эффективная разрядность входных данных понижается на один бит. Блочную память RAMB18E1 преобразователь не использует.
Соответственно, чтобы найти знак числа, необходимо взять старший (знаковый) бит входных данных. Алгоритм поиска мантиссы MAN(A) на базе примитивов кристалла ПЛИС следующий:
- взять модуль входного числа (операция «исключающее ИЛИ»);
- произвести поиск старшего значащего бита (MSB SEEKER);
- по старшему значащему биту сформировать величину сдвига мантиссы;
- перемножить модуль числа и значение сдвига, получив нормализованную мантиссу (FRAC SHIFTER).
Для поиска экспоненты EXP(A) необходимо:
- взять модуль входного числа (операция «исключающее ИЛИ»);
- произвести поиск старшего значащего бита (MSB SEEKER);
- вычесть из числа 32 инвертированный индекс значащего бита;
- прибавить 1 к полученному результату с учётом логики поиска ненулевого входного значения (LUT ZERO FORMER).
Поскольку мантисса получается путём умножения модуля действительного числа на некоторую «маску», от которой зависит сдвиг входного числа без знака, то для её поиска необходим блок DSP48E1. Процедура поиска и формирования мантиссы происходит в узле FRAC SHIFTER и проиллюстрирована на рисунке 3.

Как видно, мантисса формируется в два этапа. На первой стадии с помощью логических ресурсов LUT из входного числа создаётся множитель LUT INIT = 216 – MSB. На второй стадии входные данные умножаются на величину сдвига в узле DSP48E1. На выходе умножителя образуется нормализованная мантисса FRAC(A). Согласно описанию, для умножения чисел без знака максимальная разрядность одного из множителей блока DSP48E1 равна 17, следовательно, мантисса и формируемый сдвиг не могут иметь большую разрядность. Это ограничение ещё раз обуславливает тот факт, что мантисса чисел в формате FP23 имеет разрядность 17. Старший бит мантиссы для ненулевых чисел равен 1, зарезервирован и применяется в операции поиска результирующей мантиссы, но не отображается в выходном представлении числа для нормализованного вида. Этот бит можно вывести и использовать в общем представлении слова, тогда разрядность выходного слова равна 24 битам.
Для уменьшения объёма занимаемых ресурсов кристалла блок DSP48E1 можно исключить. Тогда узел поиска мантиссы преобразуется в быстрый сдвиговый регистр (Barrel Shifter), но при этом несколько уменьшается производительность вычислительного узла. Для некоторых кристаллов ПЛИС количество DSP48E1 невелико, и лишние траты ресурсов критичны, поэтому при частом использовании блоков FP23 есть возможность выбрать тот или иной вариант. Кроме того, для варианта с использованием быстрого сдвига суммарная задержка на полное выполнение операции преобразования уменьшается на один такт, что крайне важно для задач, где требуется минимальная задержка на выполнение операций и преобразований данных.
Узлы суммирования для поиска экспоненты сделаны в виде полных двоичных сумматоров, для реализации которых применяются логические компоненты MUXCY, XORCY и CARRY CHAIN, входящие в состав базовых ячеек SLICEL и SLICEM. Подробное описание можно найти в любой литературе, посвящённой программируемой логике.
Преобразование FP23 в FIX16
Преобразование данных из формата FP23 в FIX16 производится в четыре простых логических этапа. На рисунке 4 изображена структурная схема преобразования данных из формата FP23 в натуральный двоичный код.

Алгоритм поиска двоичного знакового числа A состоит из нескольких последовательных действий:
- из экспоненты EXP(A) вычесть значение SCALE (масштабирование выходных данных);
- сформировать сдвиговую маску 2(EXP(A) – SCALE);
- к мантиссе прибавить скрытый бит IMPL(A) и умножить результат на величину сдвига;
- учесть знак числа SIGN(A) путём взятия операции «исключающее ИЛИ».
Как и для узла прямого преобразования в формат FP23, в этой схеме для экономии ресурсов ПЛИС блок DSP48E1 можно заменить быстрым сдвиговым регистром, выполненным на ячейках SLICEM.
Умножение
Умножение чисел в формате FP23 – одна из самых простых и логичных операций.

Аппаратно алгоритм умножения реализован следующим образом (см. рис. 5):
- умножение мантисс в узле DSP48E1;
- нормализация мантиссы (взятие в качестве мантиссы разрядов из битовой сетки [32…17] или [31…16], в зависимости от значения старшего значащего бита);
- арифметическое сложение экспонент;
- вычитание из суммы экспонент числа 16;
- если 33-й бит произведения мантисс равен 0, то из экспоненты результата вычитается ещё 1;
- определение знака произведения с помощью операции «исключающее ИЛИ».
В схеме не отражена логика умножения на нулевое число, но алгоритмически она сводится к тому, что если экспонента любого входного числа равна нулю, то результат на выходе также равен нулю. На ПЛИС поиск нуля организован с помощью логических функций AND и OR на базовых блоках LUT в составе SLICEL.
Число 16 вычитается из суммы экспонент для учёта скрытых битов в мантиссах входных чисел, которые дают двойную прибавку к экспонентам. Сумматоры и вычитатели в узле умножения чисел с плавающей запятой также реализованы по схеме двоичного полного сумматора.
Сложение и вычитание
Сложение и вычитание чисел в формате FP23 – самая сложная и затратная по ресурсам операция.

Сложение состоит из следующих фундаментальных стадий (см. рис. 6):
- приведение операндов к одной экспоненте (выравнивание);
- арифметическое сложение мантисс;
- нормализация результата (подбор такой экспоненты, чтобы 16-й бит мантиссы был равен 1).
Аппаратно алгоритм сложения реализован следующим образом:
- операнды «A» и «B» сравниваются по модулю, и если |А| < |B|, числа меняются местами (мультиплексор данных);
- вычисляется разность экспонент операндов, а результат определяет, на сколько разрядов нужно сдвинуть мантиссу числа «B» вправо, чтобы привести числа к одной экспоненте;
- по разности экспонент формируется число 2(16 – (EXP(A) – EXP(B))), на которое умножается мантисса числа «В»;
- результат умножения складывается с мантиссой нового числа «A»;
- в полученном числе определяется номер старшего значащего бита MSB, формируется число 2(16 – MSB);
- проводится нормализация мантиссы путём умножения суммы мантисс на число 2(16 – MSB);
- формируется экспонента числа EXP(C) = EXP(A) – MSB + 1.
Вычитание реализовано аналогично сложению. Единственное отличие только в том, что у вычитаемого операнда инвертируется знак SIGN(B). Блоки DSP48E1 также можно заменить на быстрый сдвиговый регистр, и наоборот (компромисс между ресурсами и производительностью кристалла).
Ресурсы ПЛИС
Результаты синтеза и задержка распространения на выполнение операции для каждого узла сведены в таблицу 2. Из неё видно, что самой простой и быстрой операцией является умножение двух чисел в формате FP23.

Объём занимаемых ресурсов после синтеза для всех узлов приведён в общем лог-файле. Пример результатов синтеза для умножителя «FP23» показан в листинге.


На рисунке 7 показана трассировка компонента умножителя внутри кристалла ПЛИС в среде Xilinx FPGA Editor. Большой синий блок слева – узел DSP48, остальные блоки – конфигурационные ресурсы кристалла. Голубые линии – сигналы и межсоединения внутри ПЛИС.
Заключение
Все узлы реализованных компонентов для формата FP23 написаны на языке описания цифровых схем – VHDL. Для проверки правильности работы узлов на языке С++ написана небольшая тестовая программа, которая содержит функции математических операций c плавающей запятой на ПЛИС. Верификация проводилась с помощью систем автоматизированного проектирования для ПЛИС – Aldec Active-HDL и Xilinx ISE Desing Suite.

Сравнительный анализ компонентов с плавающей запятой для IP-CORE Xilinx и специализированного формата FP23 приведён в таблице 3. Видно, что производительность для ядер FP23, реализованных оптимальным образом с учётом логики кристалла ПЛИС, выше. При этом ресурсов затрачено не больше, а в некоторых случаях в два раза меньше, особенно для узлов DSP48. Задержка на выполнение операций сопоставима.
Компоненты FP23 были реализованы автором при решении специализированных радиотехнических задач, в частности, использовались для создания узлов БПФ/ОБПФ на ПЛИС в задачах цифровой обработки больших потоков данных. Исходные коды RTL-описаний, программу тестирования и результаты синтеза можно найти по ссылке [1].
Литература
- www.github.com/capitanov/fp23_logic.
- Xilinx LogiCORE IP Floating-Point Operator. DS335. 2011. March 1.
- Altera Floating-Point IP Cores User Guide. UG-01058. 2015.07.30.
- ISO/IEC/IEEE 60559 (IEEE Std. 754–2008).
- www.habrahabr.ru/post/112953.
- Muller J.-M., Brisebarre, N. Handbook of Floating-Point Arithmetic. 2010.
Если вам понравился материал, кликните значок — вы поможете нам узнать, каким статьям и новостям следует отдавать предпочтение. Если вы хотите обсудить материал —не стесняйтесь оставлять свои комментарии : возможно, они будут полезны другим нашим читателям!

