Skip to content

Commit

Permalink
Disable rounding for float conversion (#2337)
Browse files Browse the repository at this point in the history
Fixes #2336. Currently running into the same problem as
#2335 (comment)

@ekiwi how did you fix it on the Rust side?
  • Loading branch information
rachitnigam authored Nov 6, 2024
1 parent 351af02 commit f44cf8f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
15 changes: 12 additions & 3 deletions calyx-py/calyx/numeric_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,14 @@ def bitnum_to_fixed(bitnum: Bitnum, int_width: int) -> FixedPoint:


@dataclass
class FloatingPoint(NumericType):
class IEEE754Float(NumericType):
"""Represents a floating point number."""

def __init__(self, value: str, width: int, is_signed: bool):
super().__init__(value, width, is_signed)

assert width in [32, 64], "Floating point numbers must be either 32 or 64 bits."

if self.bit_string_repr is None and self.hex_string_repr is None:
# The decimal representation was passed in.
packed = struct.pack("!f", float(self.string_repr))
Expand All @@ -353,8 +355,15 @@ def __init__(self, value: str, width: int, is_signed: bool):
self.uint_repr = int(self.bit_string_repr, 2)
self.hex_string_repr = np.base_repr(self.uint_repr, 16)

def to_dec(self, round_place: int):
def as_str(self):
float_value = struct.unpack(
"!f", int(self.bit_string_repr, 2).to_bytes(4, byteorder="big")
)[0]
return round(float_value, round_place)
if self.width == 32:
return str(np.float32(float_value))
elif self.width == 64:
return str(np.float64(float_value))
else:
raise InvalidNumericType(
f"Unsupported width: {self.width} for floating point."
)
18 changes: 11 additions & 7 deletions fud/fud/stages/verilator/json_to_dat.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import simplejson as sjson
import numpy as np
from calyx.numeric_types import FixedPoint, Bitnum, FloatingPoint, InvalidNumericType
import logging as log
from pathlib import Path

import numpy as np
import simplejson as sjson
from calyx.numeric_types import Bitnum, FixedPoint, IEEE754Float, InvalidNumericType

from fud.errors import Malformed
import logging as log


def float_to_fixed(value: float, N: int) -> float:
Expand Down Expand Up @@ -41,8 +43,8 @@ def parse(hex_value: str):
else:
return int(bn.str_value())
else:
fp = FloatingPoint(hex_value, **args)
return fp.to_dec(round_place=2)
fp = IEEE754Float(hex_value, **args)
return float(fp.as_str())

with path.open("r") as f:
lines = []
Expand Down Expand Up @@ -95,13 +97,15 @@ def provided(x, y):

def convert(x, round: bool, is_signed: bool, width: int, is_bn: bool, int_width=None):
with_prefix = False

# If `int_width` is not defined, then this is a `Bitnum`
if int_width is None:
if is_bn:
return Bitnum(x, width, is_signed).hex_string(with_prefix)
else:
return FloatingPoint(x, width, is_signed).hex_string(with_prefix)
return IEEE754Float(x, width, is_signed).hex_string(with_prefix)

# Otherwise, this is a fixed-point number.
try:
return FixedPoint(x, width, int_width, is_signed).hex_string(with_prefix)
except InvalidNumericType as error:
Expand Down
4 changes: 2 additions & 2 deletions tests/correctness/ieee754-float/parse-and-print.expect
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"inp": [
15.12
15.1239
],
"out": [
15.12,
15.1239,
0.56
]
}

0 comments on commit f44cf8f

Please sign in to comment.