SarBon88 0 7 июня, 2023 Опубликовано 7 июня, 2023 · Жалоба Всем добрый день. Пытаюсь реализовать деление двоичных чисел с плавающей точкой в формате IEEE754. Если с определением знака и экспоненты проблем не возникает, то в определении мантиссы частного возникли сложности. Пытаюсь реализовать ниже представленный алгоритм: Спойлер Деление с неподвижным делителем и сдвигаемым влево делимым. Деление начинается со сдвига влево делимого. Далее на вход сумматора подаётся сдвинутое влево делимое, образуется частичный остаток путём подсуммирования дополнительного кода отрицательного делителя, и очередная цифра частного заносится в освободившийся при сдвиге X разряд. 1) берутся модули делимого и делителя, 2) исходное значение частичного остатка полагается равным старшим разрядам делимого, и 3) частичный остаток удваивается путём сдвига на один разряд влево, при этом в освобождающийся при сдвиге младший разряд частичного остатка заносится очередная цифра делимого 4) если сдвинутый частичный остаток >0, то из него вычитается делитель; в противном случае прибавляется делитель. 5) Очередная цифра частного равна 1, если результат четвёртого пункта положителен, и 0, если отрицателен. Выполнение повторяется с третьего пункта до получения всех цифр модуля частного. В конце деления, если остаток отрицателен, то он восстанавливается путём подсуммирования делителя. Ниже представлен код. В модуль параллельно поступают 2 16 разрядных числа с плавающей точкой, у которых [9:0] биты - мантиссы, которые и необходимо разделить. На выходе нужно получить частное и параллельно передать его. Счетчик начинает работать, когда числа поступят. Подозреваю, что проблема получения некорректного результата может быть связана с проверкой знака остатка. Буду благодарен за любые идеи! Спойлер module div_fraction(clk, res, divisible, divider, out); input clk, res; input [15:0] divisible, divider; output reg [9:0] out; reg [9:0] reg_quotient; reg signed [10:0] remains; reg signed [9:0] divider_copy; reg [3:0] cnt; always@(posedge clk) begin if(!res) reg_quotient <= 0; else if((divisible !== 16'bX) && (divider !== 16'bX)) begin cnt <= 4'b1010; divider_copy <= divider[9:0]; remains <= divisible[9:0]; reg_quotient <= 0; if (cnt >= 0)begin cnt <= cnt - 1'b1; remains <= {1'b0, remains[8:0], 1'b0}; if(!remains[10]) begin remains <= remains + (~divider_copy + 1'b1); reg_quotient <= {reg_quotient[8:0], 1'b1}; end else begin remains <= remains + divider_copy; reg_quotient <= {reg_quotient[8:0], 1'b0}; end end end end endmodule Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 45 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба Что мешает взять готовые библиотеки? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба Для начала отделите инициализацию cnt, divider_copy, remains и reg_quotient от их дальнейшего вычисления. Сейчас у вас на каждом такте вычисляется одно и тоже 9 hours ago, SarBon88 said: Счетчик начинает работать, когда числа поступят. Для определения что числа поступили используется отдельный сигнал, а не проверка данных на X - эта конструкция синтезируется не так, как вы ожидаете 🙂 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SarBon88 0 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба Понял, то есть необходимо начинать счет по сигналу load(который приходит из предыдущего модуля), сигнализирующий о полной передачи чисел. Можете, пожалуйста, еще подсказать на счет самой операции деления? Смущает проверка знака частичного остатка. Спойлер 1 час назад, xvr сказал: Для начала отделите инициализацию cnt, divider_copy, remains и reg_quotient от их дальнейшего вычисления. Сейчас у вас на каждом такте вычисляется одно и тоже Для определения что числа поступили используется отдельный сигнал, а не проверка данных на X - эта конструкция синтезируется не так, как вы ожидаете 🙂 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба посмотрите алгоритм и его реализуйте пошагово. Там пример есть - добейтесь соответствия в симуляторе для начала для данного примера... Определитесь с архитектурой FSM или pipeline реализации. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SarBon88 0 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба Спасибо за материал, пример достаточно наглядный, попробую реализовать. Спойлер 13 минут назад, Maverick_ сказал: посмотрите алгоритм и его реализуйте пошагово. Там пример есть - добейтесь соответствия в симуляторе для начала для данного примера... Определитесь с архитектурой FSM или pipeline реализации. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 8 июня, 2023 Опубликовано 8 июня, 2023 · Жалоба 2 hours ago, SarBon88 said: Смущает проверка знака частичного остатка. Знак проверяется правильно, а вот сдвиг частичного остатка (п3 в вашем алгоритме) делается не правильно. Ну и собственно реализация в целом неправильная - у вас описан алгоритм, а не схема. HDL язык - это не язык програмирования! Это язык описания аппаратуры. Посмотрите какие нибудь примеры, как на нём пишут. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 14 июня, 2023 Опубликовано 14 июня, 2023 · Жалоба В 08.06.2023 в 15:54, xvr сказал: Знак проверяется правильно, а вот сдвиг частичного остатка (п3 в вашем алгоритме) делается не правильно. Ну и собственно реализация в целом неправильная - у вас описан алгоритм, а не схема. HDL язык - это не язык програмирования! Это язык описания аппаратуры. Посмотрите какие нибудь примеры, как на нём пишут. А ещё лучше -- разобраться, как это делается в реальном железе, на логических элементах, триггерах и прочая. Если подходить к HDL как к языку программирования, хорошего результата не будет (даже если что-то и будет работать). Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться