@@ -14,6 +14,7 @@ import Clash.Sized.BitVector (BitVector, Bit)
1414import Clash.Sized.Index (Index )
1515import Clash.Sized.Signed (Signed )
1616import Clash.Sized.Unsigned (Unsigned )
17+ import Clash.Sized.Vector as Vec (Vec , repeat , mapAccumR )
1718
1819import Data.Bifunctor (bimap )
1920import Data.Functor.Identity (Identity (.. ))
@@ -22,11 +23,14 @@ import Data.Word (Word8, Word16, Word32, Word64)
2223import GHC.TypeLits (KnownNat , type (<= ))
2324
2425-- $setup
26+ -- >>> :m -Prelude
27+ -- >>> import Clash.Prelude
2528-- >>> import Clash.Class.Counter
2629-- >>> import Clash.Sized.BitVector (BitVector)
2730-- >>> import Clash.Sized.Index (Index)
2831-- >>> import Clash.Sized.Signed (Signed)
2932-- >>> import Clash.Sized.Unsigned (Unsigned)
33+ -- >>> import Clash.Sized.Vector (Vec(..), iterate)
3034
3135-- | t'Clash.Class.Counter.Counter' is a class that composes multiple counters
3236-- into a single one. It is similar to odometers found in olds cars,
@@ -193,3 +197,26 @@ instance (Counter a0, Counter a1) => Counter (a0, a1) where
193197 (overflowA, a1) = countPredOverflow a0
194198
195199genTupleInstances maxTupleSize
200+
201+ rippleR :: (a -> (Bool , a )) -> Vec n a -> (Bool , Vec n a )
202+ rippleR f = mapAccumR step True
203+ where
204+ step carry x = if carry then f x else (False , x)
205+
206+ -- | Counters on vectors increment from right to left.
207+ --
208+ -- >>> type T = Vec 2 (Index 10)
209+ -- >>> countSucc @T (0 :> 0 :> Nil)
210+ -- 0 :> 1 :> Nil
211+ -- >>> countSucc @T (0 :> 1 :> Nil)
212+ -- 0 :> 2 :> Nil
213+ -- >>> countSucc @T (0 :> 9 :> Nil)
214+ -- 1 :> 0 :> Nil
215+ -- >>> iterate (SNat @5) (countSucc @T) (9 :> 8 :> Nil)
216+ -- (9 :> 8 :> Nil) :> (9 :> 9 :> Nil) :> (0 :> 0 :> Nil) :> (0 :> 1 :> Nil) :> (0 :> 2 :> Nil) :> Nil
217+ instance (Counter a , KnownNat n , 1 <= n ) => Counter (Vec n a ) where
218+ countMin = Vec. repeat countMin
219+ countMax = Vec. repeat countMax
220+
221+ countSuccOverflow = rippleR countSuccOverflow
222+ countPredOverflow = rippleR countPredOverflow
0 commit comments