Мне нужно умножить целое число в диапазоне от 0 до 1023 на 1023 и разделить результат на число в диапазоне от 1 до 1023 в аппаратном обеспечении (реализация Verilog/fpga). Умножение выполняется прямолинейно, поскольку я, вероятно, могу обойтись простым сдвигом на 10 бит (и, если необходимо, я вычту дополнительные 1023). Хотя разделение немного интересное. Площадь/мощность для меня не критичны (у меня ПЛИС, так что ресурсы уже есть). Задержка (в пределах разумного) не имеет большого значения, пока я могу конвейеризировать дизайн. Очевидно, есть несколько вариантов с разными компромиссами, но мне интересно, есть ли «очевидный» или «легкий» алгоритм для такой ситуации. Учитывая ограниченный диапазон операндов и изобилие ресурсов, которые у меня есть (bram и т. д.), мне интересно, нет ли чего-то очевидного, что нужно сделать.
Какой алгоритм деления следует использовать для аппаратного деления небольших целых чисел?
Ответы (2)
Если вы можете работать с точностью с фиксированной точкой, а не с целыми числами, возможно, вы сможете изменить:
разделить результат на число в диапазоне от 1 до 1023
для умножения на число в диапазоне от 1 до 1/1023, т.е. предварительно вычислите деление и сохраните его как коэффициент для умножения.
Если вы можете предварительно вычислить все, и у вас есть запасной множитель 20x20 и какой-то способ сохранить предварительно вычисленное число, тогда воспользуйтесь предложением Моргана. Вам нужно предварительно вычислить 20-битное множимое (частное 10b, остаток 10b), умножить на первое число 10b и взять нижние 30b результата 40b.
В противном случае легкая задача — это невосстанавливающее деление, поскольку вы говорите, что задержка не важна (в сети много чего, большая часть непонятна). у вас есть 20-битный числитель (результат вашего (1023 x) умножения) и 10-битный знаменатель. Это дает частное 20b и остаток 10b (т.е. 20 бит для целой части ответа и 10 бит для дробной части, что дает ответ 30b).
Фактическое аппаратное обеспечение довольно тривиально: сумматор/вычитатель 11 бит, регистр сдвига 31 бит и регистр 10 бит или 11 бит для хранения делителя. Вам также понадобится небольшой FSM, чтобы управлять им (2b). Вы должны выполнять сравнение, складывать или вычитать и сдвигать каждый такт, и вы получите ответ за 21 такт. Я думаю. :)