Skip to content

Commit

Permalink
some fixes to the converter
Browse files Browse the repository at this point in the history
  • Loading branch information
saw235 committed Oct 16, 2024
1 parent 626d0d1 commit d75a53e
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 24 deletions.
38 changes: 20 additions & 18 deletions lib/src/arithmetic/floating_point/floating_point_converter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ class FloatingPointConverter extends Module {
// Handle sign
_result.sign <= source.sign;

Logic normalizedExponent = Logic(name: 'normalizedExponent');
Logic normalizedMantissa = Logic(name: 'normalizedMantissa');
Logic normalizedExponent =
Logic(name: 'normalizedExponent', width: destExponentWidth);
Logic normalizedMantissa =
Logic(name: 'normalizedMantissa', width: destMantissaWidth);

normalizedExponent < _normalizeSubnormalExponent();
normalizedMantissa < _normalizeSubnormalMantissa();

final normalizedFP = FloatingPoint(exponentWidth: 0, mantissaWidth: 0);
normalizedFP <
FloatingPointValue(
sign: source.sign.value,
exponent: normalizedExponent.value,
mantissa: normalizedMantissa.value,
);
final normalizedFP = FloatingPoint(exponentWidth: destExponentWidth, mantissaWidth: destMantissaWidth);

normalizedFP.sign <= source.sign;
normalizedFP.exponent <= normalizedExponent;
normalizedFP.mantissa <= normalizedMantissa;

If.block([
Iff(source.isNaN(), [
Expand Down Expand Up @@ -97,15 +97,15 @@ class FloatingPointConverter extends Module {
/// mantissa of the destination [FloatingPoint] respectively.
FloatingPoint _handleNaN(FloatingPoint sourceFP, int destExponentWidth,
int destMantissaWidth) =>
_packSpecial(
packSpecial(
source: sourceFP,
destExponentWidth: destExponentWidth,
destMantissaWidth: destMantissaWidth,
isNaN: true);

FloatingPoint _handleInfinity(FloatingPoint sourceFP, int destExponentWidth,
int destMantissaWidth) =>
_packSpecial(
packSpecial(
source: sourceFP,
destExponentWidth: destExponentWidth,
destMantissaWidth: destMantissaWidth,
Expand Down Expand Up @@ -163,8 +163,10 @@ class FloatingPointConverter extends Module {
return packNormal;
}

Logic _normalizeSubnormalExponent() => Const(0);
Logic _normalizeSubnormalMantissa() => Const(0);
Logic _normalizeSubnormalExponent() =>
Const(0, width: destExponentWidth, fill: true);
Logic _normalizeSubnormalMantissa() =>
Const(0, width: destMantissaWidth, fill: true);

FloatingPoint _handleOverflow(
{required FloatingPoint source,
Expand All @@ -189,7 +191,8 @@ class FloatingPointConverter extends Module {
/// [sign] is the sign bit of the special number.
///
/// [isNaN] is true if the special number is a NaN, false if it is an infinity.
FloatingPoint _packSpecial(
@visibleForTesting
FloatingPoint packSpecial(
{required FloatingPoint source,
required int destExponentWidth,
required int destMantissaWidth,
Expand All @@ -198,10 +201,9 @@ class FloatingPointConverter extends Module {
exponentWidth: destExponentWidth, mantissaWidth: destMantissaWidth);

pack.exponent <= Const(1, width: destExponentWidth, fill: true);
pack.sign <= source.sign;

if (isNaN) {
pack.mantissa <= Const(1) << (destMantissaWidth - 1);
pack.mantissa <= Const(1, width: destMantissaWidth, fill: true) << (destMantissaWidth - 1);
} else {
pack.mantissa <= Const(0, width: destMantissaWidth, fill: true);
}
Expand All @@ -227,7 +229,7 @@ class FloatingPointConverter extends Module {
required int destExponentWidth,
required int destMantissaWidth,
required bool isNaN}) =>
_packSpecial(
packSpecial(
source: source,
destExponentWidth: destExponentWidth,
destMantissaWidth: destMantissaWidth,
Expand Down Expand Up @@ -269,7 +271,7 @@ class FloatingPointConverter extends Module {
Logic _roundMantissa(Logic sourceMantissa, int destMantissaWidth,
FloatingPointRoundingMode roundingMode) {
final shift = sourceMantissa.width - destMantissaWidth;
final roundBit = Const(1) << (shift - 1);
final roundBit = Const(1, width: sourceMantissa.width) << (shift - 1);
final mask = roundBit - 1;
final roundCondition = (sourceMantissa & roundBit) &
((sourceMantissa & mask) | (roundBit << 1));
Expand Down
8 changes: 4 additions & 4 deletions lib/src/arithmetic/floating_point/floating_point_logic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class FloatingPoint extends LogicStructure {
/// represent very small numbers that are close to zero.
Logic isSubnormal() =>
exponent.eq(LogicValue.filled(exponent.width, LogicValue.zero)) &
mantissa.neq(LogicValue.filled(exponent.width, LogicValue.zero));
mantissa.neq(LogicValue.filled(mantissa.width, LogicValue.zero));

/// Return the zero exponent representation for this type of FloatingPoint
Logic zeroExponent() => Const(LogicValue.zero).zeroExtend(exponent.width);
Expand All @@ -73,21 +73,21 @@ class FloatingPoint extends LogicStructure {
/// infinite value.
Logic isInfinity() =>
exponent.eq(LogicValue.filled(exponent.width, LogicValue.one)) &
mantissa.eq(LogicValue.filled(exponent.width, LogicValue.zero));
mantissa.eq(LogicValue.filled(mantissa.width, LogicValue.zero));

/// Return a Logic true if the exponent is all ones and mantissa is non-zero,
/// indicating an infinite value.
Logic isNaN() =>
exponent.eq(LogicValue.filled(exponent.width, LogicValue.one)) &
mantissa.neq(LogicValue.filled(exponent.width, LogicValue.zero));
mantissa.neq(LogicValue.filled(mantissa.width, LogicValue.zero));

/// Return a Logic true if the FloatingPoint contains a zero value.
///
/// Zero values for FloatingPoint are defined as having an exponent of zero
/// and a mantissa of zero.
Logic isZero() =>
exponent.eq(LogicValue.filled(exponent.width, LogicValue.zero)) &
mantissa.eq(LogicValue.filled(exponent.width, LogicValue.zero));
mantissa.eq(LogicValue.filled(mantissa.width, LogicValue.zero));

@override
void put(dynamic val, {bool fill = false}) {
Expand Down
37 changes: 35 additions & 2 deletions test/arithmetic/floating_point/floating_point_conversion_test.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
import 'dart:convert';
import 'dart:math';
import 'package:rohd_hcl/rohd_hcl.dart';
import 'package:test/test.dart';
import 'package:rohd/rohd.dart';


void main() {
test('FP: FP16 to FP32 conversion test', () {
test('FP: packSpecial test', () {
final fp32 = FloatingPoint32()
..put(FloatingPoint32Value.fromDouble(1.5).value);

print(Const(0, width: 3).eq(Const(0, width: 1)));
const fp16MantissaWidth = 11;
const fp16ExponentWidth = 5;

final converter_fp32_fp16 = FloatingPointConverter(fp32,
destExponentWidth: fp16ExponentWidth,
destMantissaWidth: fp16MantissaWidth,
name: 'FP32_to_FP16_Converter');

final result = converter_fp32_fp16.result;
final packedFP = converter_fp32_fp16.packSpecial(source: fp32, destExponentWidth: fp16ExponentWidth, destMantissaWidth: fp16MantissaWidth, isNaN: false);

expect(packedFP.isInfinity(), true);
});

test('FP: FP64 to FP32 conversion test', () {
// final fp64 = FloatingPoint64()
// ..put(FloatingPoint64Value.fromDouble(1.5).value);

// const fp16MantissaWidth = 11;
// const fp16ExponentWidth = 5;

// final converter = FloatingPointConverter(fp64,
// destExponentWidth: fp16ExponentWidth,
// destMantissaWidth: fp16MantissaWidth,
// name: 'FP64_to_FP32_Converter');

// final result = converter.result.value;
// expect(result, equals(FloatingPoint32Value.fromDouble(1.5).value));

// final packed = converter.packSpecial(source: fp64, destExponentWidth: fp16ExponentWidth, destMantissaWidth: fp16MantissaWidth, isNaN: false);
// // expect(packed.exponent.width, matcher)


// final converter = FloatingPointConverter(fp32,
// Declare a constant for exponent width for FP16
Expand Down

0 comments on commit d75a53e

Please sign in to comment.