clash-compiler
clash-compiler copied to clipboard
`Counter` for `Vec`tors
How about something like this?
data Endian = BigEndian | LittleEndian
newtype Counters (endianness :: Endian) n a = Counters{ getCounters :: Vec n a }
deriving (Generic, NFDataX, Eq, Show)
ripple :: ((Bool -> a -> (Bool, a)) -> Bool -> Vec n a -> (Bool, Vec n a)) -> (a -> (Bool, a)) -> Vec n a -> (Bool, Vec n a)
ripple mapAccum f = mapAccum step True
where
step carry x = if carry then f x else (False, x)
instance (Counter a, KnownNat n, 1 <= n) => Counter (Counters BigEndian n a) where
countMin = Counters $ repeat countMin
countMax = Counters $ repeat countMax
countSuccOverflow = fmap Counters . ripple mapAccumR countSuccOverflow . getCounters
countPredOverflow = fmap Counters . ripple mapAccumR countPredOverflow . getCounters
instance (Counter a, KnownNat n, 1 <= n) => Counter (Counters LittleEndian n a) where
countMin = Counters $ repeat countMin
countMax = Counters $ repeat countMax
countSuccOverflow = fmap Counters . ripple mapAccumL countSuccOverflow . getCounters
countPredOverflow = fmap Counters . ripple mapAccumL countPredOverflow . getCounters
Mostly I just want to be able to use a Counter BigEndian n (Index 10)
as the world's least-effort BCD counter...