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

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

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

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

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

1
2module fp32mul
3(
4    input   [31:0]  a,
5    input   [31:0]  b,
6    output  [31:0]  c
7);
8
9wire sign = a[31] ^ b[31];
10
11// Значение порядков и мантиссы
12wire [ 7:0] pa = a[30:23], pb = b[30:23];
13wire [22:0] ma = a[22:0],  mb = b[22:0];
14
15// Умножение нормализованных чисел
16wire [47:0] t   = {|pa, ma} * {|pb, mb};
17wire [22:0] m   = t[47] ? t[46:24] : t[45:23];  // Результирующая мантисса
18wire [ 8:0] p0  = pa + pb + t[47],              // Переполнение вверх
19            p1  = p0 - 8'h7F;                   // Переполнение вниз
20
21// Если порядок более 255, то +inf, если менее 0, то это будет 0
22assign c = {sign, p0[8] ? {31{1'b1}} : p1[8] ? {31{1'b0}} : {p1, m}};
23
24endmodule
На вход подаются нормализованные float a и b, на выход получается c.