diff --git a/src/peakrdl_busdecoder/sv_int.py b/src/peakrdl_busdecoder/sv_int.py index 96d47ec..bd77d9c 100644 --- a/src/peakrdl_busdecoder/sv_int.py +++ b/src/peakrdl_busdecoder/sv_int.py @@ -1,8 +1,15 @@ +from typing import Literal + + class SVInt: def __init__(self, value: int, width: int | None = None) -> None: self.value = value self.width = width + if width is not None: + self.width = max(width, self.value.bit_length()) + # assert (width is None) or (self.value.bit_length() <= width), "Value does not fit in specified width" + def __str__(self) -> str: if self.width is not None: # Explicit width @@ -19,3 +26,27 @@ class SVInt: return SVInt(self.value + other.value, max(self.width, other.width)) else: return SVInt(self.value + other.value, None) + + def __sub__(self, other: "SVInt") -> "SVInt": + if self.width is not None and other.width is not None: + return SVInt(self.value - other.value, max(self.width, other.width)) + else: + return SVInt(self.value - other.value, None) + + def __len__(self) -> int: + if self.width is not None: + return self.width + else: + return self.value.bit_length() + + def to_bytes(self, byteorder: Literal["little", "big"] = "little") -> bytes: + byte_length = (self.value.bit_length() + 7) // 8 + return self.value.to_bytes(byte_length, byteorder) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SVInt): + return NotImplemented + return self.value == other.value and self.width == other.width + + def __hash__(self) -> int: + return hash((self.value, self.width)) \ No newline at end of file