Арифметика в HDL и Fixed-Point
Страница в процессе разработки. |
При генерации кода в Engee, а также при работе с Fixed-Point (фиксированной точкой) в среде вычислений и в симуляции, для арифметических операций действуют определенные правила.
Правила арифметики в Си имеют множество неявных преобразований, и тип результата математической операции выводится, исходя из знаков и рангов аргументов.
Правила арифметических операций в HDL (языки описания аппаратуры, напр. Verilog, Chisel) лаконичны, но осложняются произвольной шириной аргументов, а также фиксированной точкой.
Правила: кратко и словами
-
Если все типы аргументов беззнаковые — тип результата беззнаковый. Иначе — тип результата знаковый.
-
Ширина типа не ограничивается 8/16/32/64 битами, а может быть произвольным натуральным числом до 128 включительно.
-
Тип результата подбирается так, чтобы не произошло переполнения.
Операция |
Тип результата |
Пример |
---|---|---|
Сложение |
Минимально необходимый тип, вмещающий весь диапазон возможных значений результата |
|
Умножение |
Ширина типа результата — сумма ширин типов аргументов, то же с дробной частью |
|
Fixed-Point
Наряду с числами с плавающей точкой, при разработке программ и железа используются числа с фиксированной точкой. Они менее гибкие, чем числа с плавающей точкой, но операции с числами с фиксированной точкой обычно исполняются быстрее. Ниже представлены основные концепции чисел с фиксированной точкой.
В Engee на данный момент используется binary-point-only (power-of-two) вариант чисел с фиксированной точкой, а не slope-bias. |
Про работу с Fixed-Point в среде вычислений Engee читайте в статье Арифметика с фиксированной точкой (Fixed-Point) в Engee. |
Binary point
Целые числа представляются в двоичном виде как сумма степеней двойки. Например, 9 в двоичной системе это :
Номер бита от MSB (наиболее значимого) к LSB (наименее значимому) |
3 |
2 |
1 |
0 |
Значение |
1 |
0 |
0 |
1 |
Степень двойки * значение бита |
|
|
|
|
Вклад в ответ |
8 |
0 |
0 |
1 |
Чтобы представить в двоичном виде нецелые числа, можно после нулевого бита мысленно поставить точку, и начать считать по отрицательным степеням двойки. Например, 9.625
кодируется как :
Номер бита от MSB (наиболее значимого) к LSB (наименее значимому) |
3 |
2 |
1 |
0 |
-1 |
-2 |
-3 |
Значение |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
Степень двойки * значение бита |
|
|
|
|
|
|
|
Вклад в ответ |
8 |
0 |
0 |
1 |
0.5 |
0 |
0.125 |
Определения
-
Ширина типа — количество бит, кодирующих значения типа.
-
Количество «дробных» битов это длина дробной части (Fraction Length), также будет обозначаться как бинарная точка (Binary Point, BP).
-
Значение в десятичной системе счисления называется реальным значением (Real World Value, RWV).
-
Целое число, которое получилось бы, если нумеровать биты от LSB к MSB, начиная с нуля (даже для нецелых реальных значений), обозначается как stored integer, SI. Например, stored integer для — это 9, а для — 77.
При этом выполняется
Более того, длина дробной части может быть отрицательной. В таком случае stored integer домножается на модуль длины дробной части. Так, число 112 можно представить, используя всего три бита и масштабирование :
Номер бита от MSB (наиболее значимого) к LSB (наименее значимому) |
6 |
5 |
4 |
Значение |
1 |
1 |
1 |
Степень двойки * значение бита |
|
|
|
Вклад в ответ |
64 |
32 |
16 |
Также обратите внимание, что длина дробной части может превышать ширину типа. Например, можно представить в типе ширины 3 и BP 11 как :
Номер бита от MSB (наиболее значимого) к LSB (наименее значимому) |
-9 |
-10 |
-11 |
Значение |
0 |
1 |
0 |
Степень двойки * значение бита |
|
|
|
Вклад в ответ |
0 |
0.0009765625 |
0 |
Отрицательные числа кодируются как дополнение до двух (two’s complement).
Обозначения
Наиболее общую форму обозначим за fixdt(S, W, f)
в соответствии со статьей Арифметика с фиксированной точкой (Fixed-Point) в Engee. Здесь:
-
S
— 0 означает беззнаковый тип, 1 означает знаковый тип; -
W
— ширина типа; -
f
— длина дробной части (BP).
Примеры обозначений конкретных типов:
Обозначение | Значение |
---|---|
|
Беззнаковый целочисленный тип ширины 32 бита |
|
Беззнаковый целочисленный тип ширины 123 |
|
Знаковый целочисленный тип ширины 16 |
|
Знаковый тип с фиксированной точкой, ширина (общая длина) 32, длина дробной части 5 |
|
Беззнаковый тип с фиксированной точкой, ширина 32, длина дробной части 5 |
|
Беззнаковый тип с фиксированной точкой, ширина 3, длина дробной части -4 |
С точки зрения арифметики следующие типы эквивалентны: uint42 , ufix42 , ufix42_En0 , ufix42_E0 .
|
Точность
Разница между числами, отличающимися лишь в наименее значимом бите, называется точностью (precision). Точность зависит от длины дробной части следующим образом:
Например, ufix8_En3
может представить числа с точностью до 0.125, и 1.0625 округлится до 1.125, а 1.0624 округлится до 1.0. А ufix8_E3
представляет числа с точностью до 8.
Slope Bias
Альтернативным (и более гибким, но менее производительным) вариантом чисел с фиксированной точкой является slope-bias-представление, где числа кодируются как:
Binary-point-only это частный случай slope-bias, где ,
Арифметика
Перед операцией бинарные точки аргументов выравниваются, а затем происходит сложение/умножение аргументов. Например, для сложения из ufix4_En3
и из ufix2_En1
нужно сначала дописать два нуля после воображаемой точки во втором числе:
1001 (ufix4_En3)
+ 01 (ufix2_En1)
= 1.001
+ 0.100
= 1.101
А при длине дробной части 3 это .
Правила: подробно
Операция | Тип аргумента1 | Тип аргумента2 | Тип результата |
---|---|---|---|
Сложение |
|
|
Минимально необходимый тип, вмещающий весь диапазон возможных значений результата, в простых случаях |
Умножение |
|
|
|
Сложение
Ширина подбирается так, чтобы вместить возможный диапазон значений результата сложения аргументов.
Алгоритм:
-
Находим минимально возможное и максимально возможное значения, которые могли быть получены в результате сложения операндов.
-
Чтобы вычислить минимальное возможное значение результата, складываем минимальные значения типов аргументов (0 для беззнаковых чисел и для знаковых).
-
Чтобы вычислить максимальное возможное значение результата, складываем максимальные значения типов аргументов.
-
-
Находим минимальное количество бит, которые необходимы, чтобы сохранить диапазон результата.
Примеры:
-
При сложении двух
sfix5_En2
получитсяsfix6_En2
, так как нам необходимо расширить тип результата на один бит, чтобы куда-то сохранить возможный перенос из старшего разряда. При сложенииufix8_En1
иufix8_En3
получитсяufix11_En3
:1111111.1 + 11111.111 = 1111111.100 + 0011111.111 = 11011111.001
Так как bit_width .
Другие примеры:
Тип аргумента1 | Тип аргумента2 | Тип результата |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Сумма нескольких чисел
Для нескольких аргументов минимально возможная ширина аккумулятора находится для всех аргументов сразу, а не последовательно сначала для первых двух аргументов, затем для сложения предыдущего результата и третьего аргумента, и т.д. Вычисления с учетом типов одновременно всех аргументов позволяют сэкономить ширину, необходимую для сохранения результата.
Сумма элементов вектора
Для блока Sum (суммирование элементов входящего вектора, специальный режим блока Add) применяется оптимизация, позволяющая избежать вычислений в цикле (как происходит в Add), и тип результата определяется быстро. А именно, так как тип всех элементов одинаковый fixdt(S, W, f)
, можно заметить, что:
Аналогично определяется минимальное значение результата, и затем подбирается необходимая ширина типа.
Можно дать оценку, что .
Умножение
Правила вывода типа результата умножения полностью описаны в таблице раздела Правила: подробно, и распространяются по индукции и ассоциативности на любое число аргументов. Исключений или каких-то дополнительных сложностей нет.