Open rossc719g opened 2 months ago
I think a fix for this would be to introduce some primitives:
primitive primPack :: (a - > Bit n) -> a -> Bit n
primitive primUnpack :: (Bit n -> a) -> Bit n -> a
and use these as wrappers around pack
and unpack
at synthesis boundaries. The evaluator would permit these to cancel each other out as a special case, otherwise it would just use the wrapped functions.
The compiler inserts an implicit unpack when reading a port/register, and an implicit pack when writing. For "standard" types like "UInt" or "Bit", these are effectively no-ops. But when using a type with a custom Bits instance, they can generate extraneous logic. Given that the source and destination are both packed, these could be elided, and remove the extraneous logic that is generated.
See https://github.com/rossc719g/bsc_examples/blob/main/pack_unpack/README.md for a full example.
The example includes a workaround using a wrapper type.