§ Общие принципы

Взглянем правде в глаза: я так и не смог сделать модуль умножения для чисел float. Не смог. Но надо хотя бы попытаться, что ли!
Для того, чтобы перемножить два числа, которые представлены в float форме, надо для начала, узнать, как они записываются:
-1^S 2^{P-127} M
Где S-это знак, P-порядок, M-мантисса.
Чтобы умножить 2 числа, нужно перемножить мантиссы между собой, сложить степени, и применить XOR к знаку. Если же мантисса превысила число 2, то сдвинуть итоговый порядок, прибавив +1.

§ Число в верилоге

Давайте теперь представим это число в верилоге:
input [31:0] value;
...
wire        sign     = value[31];
wire [7:0]  exponent = value[30:23];
wire [23:0] mantissa = {exponent != 0, value[22:0]};
Обращу внимание на скрытую единицу! Если экспонента не будет равна 0, то тогда туда записывается 1, иначе будет 0 — такое число называется денормализованным.
Я расскажу только про умножение нормализованных чисел.
При умножении двух чисел, может получится число, которое больше по количеству значащих знаков в 2 раза. Это надо учесть и потому взять итоговый результат только из более старших знаков.

§ Модуль вычисления

wire [47:0] c = {1'b1, a[22:0]} * {1'b1, b[22:0]};

// Складывание порядков
wire [ 7:0] p = (a[30:23] + b[30:23] - 127) + c[47];

// Если мантисса >=2, то получить более старший разряд первым
wire [22:0] m = c[47] ? c[47:25] : c[46:24];

// Вычисление результата
wire [31:0] r = {a[31] ^ b[31], p, m};
На вход подаются нормализованные float, a и b, на выход получается r.
9 апр, 2022
© 2007-2022 Фрамуга улетает в парке