Я проектирую модуль с плавающей запятой в SystemVerilog, который принимает два 32-разрядных ввода в формате IEEE754, складывает их вместе и выводит результат в том же 32-разрядном формате IEEE754.
Мой вопросесть, как я могу определить, нужно ли нормализовать мой результат?
Я понимаю, что это когда вам нужно переместить «крайний левый» 1 в правильный бит, который должен быть битом 23 (начиная с бита 0)
Что у меня тяжеловремя, когда я оборачиваюсь, - это то, как я могу определить, какой правильный «самый левый» 1 бит, чтобы я мог сдвинуть мантиссу и соответственно увеличить / уменьшить биты экспоненты.
Если мое понимание верно, сложение должно иметьследующий процесс.
- Разделите биты на знак, экспоненту и мантиссу
- Добавьте «1» к мантиссе
- Сравните показатели и добавьте разницу кменьший показатель
- Сместить мантиссу меньшего показателя вправо на указанное различие, чтобы правильно «выстроить» десятичные дроби / число
- Выполнить двоичное сложение
- Нормализовать результат, еслинеобходимо
Я полагаю, что у меня есть все шаги, кроме нормализующей части, правильной.Моя проблема в том, как я могу определить, что результат не нормализован, если все, что у меня есть, это биты?
Я знаю, что он не нормализован, если результат не равен 1. (дробь).
т.е.10.10101 * 2 ^ 1 должно быть нормализовано до 1.010101 * 2 ^ 2, а .1001 * 2 ^ 2 должно быть нормализовано до 1.001 * 2 ^ 1.
В частности, я думаю, я пытаюсь спросить, как я могуотслеживать, где находится «десятичное» место после добавления двух чисел.
Например: Добавление ввода a: 0x3fc00000 (1.5) и b: 0x40500000 (3.25)
a = 0 |0111 1111 |(1) 100 0000 0000 0000 0000 0000
b = 0 |1000 0000 |(1) 101 0000 0000 0000 0000 0000
показатель степени a меньше b на разницу 1, поэтому:
a = 0 |1000 0000 |0 (1) 10 0000 0000 0000 0000 0000
b = 0 |1000 0000 |(1) 101 0000 0000 0000 0000 0000
добавление мантисс даст нам результат
1 0011 0000 0000 0000 0000 0000
Здесь мы видим «крайний левый»1 является битом 24, а не 23, поэтому мы смещаем мантиссу вправо на 1 и увеличиваем показатель степени для нормализации результата.Затем мы удаляем «самый левый» 1, поскольку он подразумевается в формате IEEE754, и мы получаем:
0 |1000 0001 |001 1000 0000 0000 0000 0000 (4.75) в качестве нашего конечного результата, который является правильным.
Учитывая этот пример, я подумал, что мне просто нужно проверить следующие случаи:
- Еслибит 24 мантиссы равен 1, сдвиг мантиссы вправо и показатель приращения
- Иначе контрольный бит 23 равен 1, если true, нормализация не требуется
- Иначе контрольный бит 22 равен 1, затем сдвиг мантиссылевая и убывающая экспонента
Однако я нахожу это верным только в некоторых случаях.Чего мне не хватает?
В моей реализации я сделал 26-битное значение для хранения суммы двух мантисс, что, я не уверен, является правильным.Бит 25 является признаком мантиссы, которая, на самом деле, мне не нужна, а биты 24 и 23 - это скрытые биты, или биты, которые не будут включены в окончательный вывод.
Например: 0x449ebbc8 (1269.868163) + 0xc60eb709 (-9133.758561) дает мне следующую мантиссу:
11 0111 1010 1101 1111 1001 0000 обратите внимание, что это 26 бит (25: 0)
Если бы я следовал предыдущему случаю, это означало бы, что «крайний левый 1» бит, исключая знаковый бит, был бы битом 24, что означало бы смещение мантиссы вправо и увеличение экспоненты.Однако правильный ответ противоположен!«Истинный» крайний левый 1 бит - это бит 22!Это означает, что я должен сместиться влево и уменьшить вместо этого!Дайте мне окончательный результат:
1 |10001011 |111 0101 1011 1111 0010 0000 (-7863,8906), что правильно.
Аналогично, добавление 0x45c59cbd и 0xc473d9dc дает мантиссе
01 1010 0111 0010 0001 1000 0010, но бит «крайний левый 1» - это не бит в 24, а в бите 23, поэтому нормализация не требуется.
Почему в первом случае янужно беспокоиться о бите 24, но не о двух других случаях?Это потому, что я добавляю противоположные знаки для других случаев?Проблема переполнения?Или есть что-то еще, чего я в принципе упускаю?
Спасибо за помощь и извините, если форматирование плохое!