53 / 63 · Теория
Фиксированная точка, округление и насыщение
Задайте диапазон форматом W,F, спроектируйте округление к чётному по guard/sticky и насыщение после округления.
Уроки доступны бесплатно. Запишитесь, чтобы сохранять прогресс.
Предварительные знания: ширины знакового сложения и умножения, арифметический правый сдвиг и overflow.
Положение точки — контракт интерпретации битов
Фиксированная точкаФиксированная точка — представление чисел с заранее заданным положением двоичной точки: к целочисленной битовой последовательности применяют постоянный масштаб. Нужно задать разрядность, знаковость и число дробных разрядов. интерпретирует целое X как . Отдельный бит десятичной точки в оборудовании не хранится. Здесь полная signed-ширина W включает знак, F — число дробных битов. В литературе Q-обозначение по-разному включает знак в целую часть, поэтому явные W,F в интерфейсе однозначнее.
При W=8,F=4 шаг 1/16, диапазон −8…7.9375. 0x18 в таком контракте означает 1.5, а не целое 24. При F=3 те же 0x18 означают 3. Соединённые проводники не гарантируют совпадения числового смысла; документируйте масштаб каждого порта.
Перед сложением выравнивают точки. При разных F расширьте значение с меньшим F и сдвиньте влево либо уменьшите больший F заданным округлением. Точная сумма двух одинаковых W,F требует W+1 бит и того же F. При умножении перемножают raw-целые, а числа дробных битов складывают.
Полное произведение двух 8-битных F=4 — signed 16 бит F=8. Для выхода 8 бит F=4 сначала удаляют четыре дробных бита, затем проверяют signed-диапазон. Если сначала усечь произведение до 8 бит, последующее насыщение уже не сможет определить исходную величину.
Отбрасывание и округление различаются
Арифметический сдвиг на d бит даёт ; отрицательные числа тоже округляются вниз. При точное частное −1.5, q=−2, что отличается от усечения к нулю. Нельзя считать, что выбор старших битов имеет для отрицательных ту же ошибку, что для положительных.
Спроектируем round-to-nearest, ties-to-even: к ближайшему, при точной середине — к чётному целому. Старший отбрасываемый бит — guard g, OR остальных — sticky t, младший сохраняемый бит q — l.
При g=0 остаток меньше половины, ничего не меняем. При g=1,t=1 — больше половины, увеличиваем. При g=1,t=0 — точная половина, добавляем 1 только к нечётному q. Для отрицательных правило то же: с нижним частным q остаток всегда удовлетворяет .
Например, −24/16=−1.5 округляется к −2, поскольку q=−2 чётно; −40/16=−2.5 тоже к −2, поскольку q=−3 нечётно. Отдельное правило «для отрицательных всегда вычитать 1» ошибочно. Без насыщения конечная числовая ошибка не больше половины выходного LSBLSB — бит с наименьшим позиционным весом. Проверяйте одновременно направление записи и правила индексации. Подробнее. Ties-to-even не гарантирует нулевую среднюю ошибку любого распределения, но уменьшает смещение, возникающее при округлении всех значений ровно посередине в одну сторону.
Преобразуем raw P=2040 из 16 бит F=8 в 8 бит F=4. 127.5 округляется к чётному 128, затем ограничивается signed-максимумом 127. Расширенную ширину нужно сохранять до последней записи.
- Вход P=2040: 16 бит · F=8
- Уменьшение масштаба: 2040 / 16 = 127.5
- равноудалённые — к чётному: Округлённое raw = 128
- Хранение после насыщения: raw 127 → 7.9375
Насыщение после завершения округления
Насыщение заменяет значения выше максимума максимумом, а ниже минимума — минимумом. В отличие от wrap большое положительное не превращается в отрицательное. Но корректно насытить уже суженное и перешедшее через границу диапазона значение нельзя.
Ниже полный комбинационный модуль signed 16 бит F=8 → signed 8 бит F=4. При фиксированном d=4 guard=p[3], sticky=p[2:0]. Увеличение для округления и сравнение диапазона выполняются в 17-битном signed-пространстве; 8 бит выбираются только в конце.
module requantize (
input logic signed [15:0] p,
output logic signed [7:0] y,
output logic saturated
);
logic signed [16:0] wide, q, rounded;
logic inc;
always_comb begin
wide = {p[15], p};
q = wide >>> 4;
inc = p[3] & ((|p[2:0]) | q[0]);
rounded = q + (inc ? 17'sd1 : 17'sd0);
saturated = 1'b0;
if (rounded > 17'sd127) begin
y = 8'sh7f;
saturated = 1'b1;
end else if (rounded < -17'sd128) begin
y = 8'sh80;
saturated = 1'b1;
end else begin
y = rounded[7:0];
end
end
endmoduleПри P=2040 частное P/16=127.5 округляется к чётному 128 и насыщается до 127. Конечное значение — 7.9375. Проверка только q=127 до округления пропустила бы переполнение. Saturated сообщает ограничение числового диапазона, а не просто потерю дробных битов.
При обобщении отдельно обрабатывайте d=0 без отбрасываемых битов и d=1 без области sticky. Скрытие недопустимого part-select внутри условия может не устранить ошибку elaboration.
Округление и насыщение добавляют сумматоры, компараторы, MUXМультиплексор — комбинационная схема, соединяющая один из нескольких входов с выходом по сигналу выбора. Соответствие битов выбора и номеров входов должно быть задано явно. Подробнее и задержку и выбираются отдельными политиками. Такое разделение отражено и в документации AMD о фиксированной точке. При накоплении нескольких членов заранее решите, сохранять ли промежуточную ширину и преобразовывать один раз в конце. Поэтапное насыщение может нарушить ассоциативность сложения, а повторное округление — накапливать малые ошибки.
Попробуйте сами
Signed-вход P ширины 16, F=8 преобразуется в signed ширины 8, F=4. Для P=24,40,−24,−40,2040 найдите floor-частное q, guard/sticky, округлённое целое, конечный raw и реальное значение. Чем опасна проверка насыщения до округления для 2040?
Прочитать объяснение
У всех входов младшие четыре бита 1000, поэтому guard=1, sticky=0. P=24: q=1 (нечётное)→2, raw=2, значение 0.125. P=40: q=2 (чётное)→2, raw=2, 0.125. P=−24: q=−2 (чётное)→−2, raw=−2, −0.125. P=−40: q=−3 (нечётное)→−2, raw=−2, −0.125. P=2040: q=127 (нечётное)→128, выше signed-максимума 8 бит, поэтому raw=127, значение 7.9375, saturated=1. Проверка только q=127 до добавления 1 в 8 битах могла бы дать wrap в 0x80 и выход −8. Увеличение и сравнение нужно завершить в расширенном signed-значении.