Skip to content

Commit

Permalink
[PyCDE] Fix casting bug
Browse files Browse the repository at this point in the history
Must pad or truncate before `hwarith.cast`.
  • Loading branch information
teqdruid committed Jan 2, 2025
1 parent 7b7a79b commit a56ba72
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
9 changes: 8 additions & 1 deletion frontends/PyCDE/src/pycde/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def _namehint_attrname(self):
return "sv.namehint"

@property
def name(self):
def name(self) -> Optional[str]:
owner = self.value.owner
if hasattr(owner,
"attributes") and self._namehint_attrname in owner.attributes:
Expand All @@ -146,6 +146,7 @@ def name(self):
return mod_type.input_names[block_arg.arg_number]
if hasattr(self, "_name"):
return self._name
return None

@name.setter
def name(self, new: str):
Expand Down Expand Up @@ -306,6 +307,12 @@ class BitsSignal(BitVectorSignal):
"""Operations on signless ints (bits). These will all return signless values -
a user is expected to reapply signedness semantics if needed."""

def _exec_cast(self, targetValueType, type_getter, width: int = None):
if width is not None and width != self.type.width:
return self.pad_or_truncate(width)._exec_cast(targetValueType,
type_getter)
return super()._exec_cast(targetValueType, type_getter)

@singledispatchmethod
def __getitem__(self, idxOrSlice: Union[int, slice]) -> BitVectorSignal:
lo, hi = get_slice_bounds(len(self), idxOrSlice)
Expand Down
20 changes: 13 additions & 7 deletions frontends/PyCDE/test/test_hwarith.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,18 @@ def construct(ports):


# CHECK: hw.module @Casting(in %in0 : i16)
# CHECK-NEXT: %0 = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> si16
# CHECK-NEXT: %1 = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> ui16
# CHECK-NEXT: %2 = hwarith.cast %0 {{({sv.namehint = ".*"} )?}}: (si16) -> i16
# CHECK-NEXT: %3 = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> si8
# CHECK-NEXT: %4 = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> ui8
# CHECK-NEXT: %5 = hwarith.cast %0 {{({sv.namehint = ".*"} )?}}: (si16) -> i8
# CHECK-NEXT: %6 = hwarith.cast %0 {{({sv.namehint = ".*"} )?}}: (si16) -> si24
# CHECK-NEXT: [[R0:%.+]] = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> si16
# CHECK-NEXT: [[R1:%.+]] = hwarith.cast %in0 {{({sv.namehint = ".*"} )?}}: (i16) -> ui16
# CHECK-NEXT: [[R2:%.+]] = hwarith.cast [[R0]] {{({sv.namehint = ".*"} )?}}: (si16) -> i16
# CHECK-NEXT: [[R11:%.+]] = comb.extract %in0 from 0 : (i16) -> i8
# CHECK-NEXT: [[R3:%.+]] = hwarith.cast [[R11]] {{({sv.namehint = ".*"} )?}}: (i8) -> si8
# CHECK-NEXT: [[R12:%.+]] = comb.extract %in0 from 0 : (i16) -> i8
# CHECK-NEXT: [[R4:%.+]] = hwarith.cast [[R12]] {{({sv.namehint = ".*"} )?}}: (i8) -> ui8
# CHECK-NEXT: [[R5:%.+]] = hwarith.cast [[R0]] {{({sv.namehint = ".*"} )?}}: (si16) -> i8
# CHECK-NEXT: [[R6:%.+]] = hwarith.cast [[R0]] {{({sv.namehint = ".*"} )?}}: (si16) -> si24
# CHECK-NEXT: [[Rc0_i16:%.+]] = hw.constant 0 : i16
# CHECK-NEXT: [[R9:%.+]] = comb.concat [[Rc0_i16]], %in0 {{({sv.namehint = ".*"} )?}}: i16, i16
# CHECK-NEXT: [[R10:%.+]] = hwarith.cast [[R9]] {{({sv.namehint = ".*"} )?}}: (i32) -> ui32
# CHECK-NEXT: hw.output
@unittestmodule(run_passes=True)
class Casting(Module):
Expand All @@ -140,6 +145,7 @@ def construct(ports):
in0u8 = ports.in0.as_uint(8)
in0s_i8 = in0s.as_bits(8)
in0s_s24 = in0s.as_sint(24)
in0s_u32 = ports.in0.as_uint(32)


# -----
Expand Down

0 comments on commit a56ba72

Please sign in to comment.