Skip to main content

Convert Floating-Point to Fixed-Point

Fixed-Point Representation​

Fixed-point numbers represent real numbers with a fixed number of decimal places.

fixed_value = integer_part + fractional_part
= integer_part × 2^0 + fractional_part × 2^(-frac_bits)

Convert to Fixed-point number (Keep F decimal places)

fixed = float × 2^F
= 2^(exp-15) × (1 + mantissa/1024) × 2^F
= 2^(exp-15+F) × (1 + mantissa/1024)

Key convertion formula

fixed = (1 + mantissa/1024) << (exp - 15 + F) 当 exp-15+F > 0
fixed = (1 + mantissa/1024) >> (15 - exp - F) 当 exp-15+F < 0

Visualization

浮点数存储:符号 | 指数 | 尾数
↓ ↓ ↓
± ×2^? ×1.xxx

定点数存储:整数部分 | 小数部分
↓ ↓
×2^0 ×2^-F

转换过程:将指数和尾数展开成整数+小数形式

Break it down and explain each part.​

Step 1: Extract the components of the floating-point number​

logic sign = fp16[15]; // sign bit
logic [4:0] exp = fp16[14:10]; // Exponent
logic [9:0] mantissa = fp16[9:0]; // Mantissa

Step 2: Stucture the full mantissa​

// Normal: The implicit integer part is 1.
// Why 1.mantissa?
// Because floating-point numbers are normalized as: 1.mantissa × 2^(exp-15)
logic [23:0] mantissa_full = {1'b1, mantissa, 13'b0};

// Denormal: When the exponent is 0, the integer part is 0.
if (exp == 0) begin
mantissa_full = {1'b0, mantissa, 13'b0};
end

Step 3: Exponential Processing​

// Compute the actual exponent offset
int exponent = exp - 15; // Actual exponent value

// Why subtract 15?
// IEEE 754 uses biased exponent
// The bias for half-precision floating-point is 15, allowing the exponent to represent negative numbers
// Actual value = 2^(exp-15) × mantissa

Step 4: Align to fixed-point format​

// Fixed-point format: fixed number of fractional bits
int shiftbits = exponent - FRAC_BITS;

// Why subtract FRACBITS?
// Fixed-point = floating-point × 2^FRAC_BITS
// Therefore, the exponent part needs to add FRACBITS
// Actual exponent = exponent + FRAC_BITS

Step 5: Shift Operation​

if (shiftbits > 0) begin
fixed = mantissafull << shiftbits; // Left shift: value increases
end else if (shiftbits < 0) begin
fixed = mantissafull >> (-shiftbits); // Right shift: value decreases
end

// Why shift this way?
// 2^(exponent) × mantissa × 2^FRACBITS = 2^(exponent+FRAC_BITS) × mantissa
// Multiplication by a power of two is achieved through shifting