{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Clash.Prelude.BitIndex where
import GHC.TypeLits (KnownNat, type (+), type (-))
import Clash.Class.BitPack (BitPack (..))
import Clash.Promoted.Nat (SNat)
import Clash.Sized.Internal.BitVector (BitVector, Bit, index#, lsb#, msb#,
replaceBit#, setSlice#, slice#, split#)
{-# INLINE (!) #-}
(!) :: (BitPack a, KnownNat (BitSize a), Enum i) => a -> i -> Bit
(!) v :: a
v i :: i
i = BitVector (BitSize a) -> Int -> Bit
forall (n :: Nat). KnownNat n => BitVector n -> Int -> Bit
index# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v) (i -> Int
forall a. Enum a => a -> Int
fromEnum i
i)
{-# INLINE slice #-}
slice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> a
-> BitVector (m + 1 - n)
slice :: SNat m -> SNat n -> a -> BitVector ((m + 1) - n)
slice m :: SNat m
m n :: SNat n
n v :: a
v = BitVector ((m + 1) + i)
-> SNat m -> SNat n -> BitVector ((m + 1) - n)
forall (m :: Nat) (i :: Nat) (n :: Nat).
BitVector ((m + 1) + i)
-> SNat m -> SNat n -> BitVector ((m + 1) - n)
slice# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v) SNat m
m SNat n
n
{-# INLINE split #-}
split :: (BitPack a, BitSize a ~ (m + n), KnownNat n) => a
-> (BitVector m, BitVector n)
split :: a -> (BitVector m, BitVector n)
split v :: a
v = BitVector (m + n) -> (BitVector m, BitVector n)
forall (n :: Nat) (m :: Nat).
KnownNat n =>
BitVector (m + n) -> (BitVector m, BitVector n)
split# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v)
{-# INLINE replaceBit #-}
replaceBit :: (BitPack a, KnownNat (BitSize a), Enum i) => i -> Bit -> a
-> a
replaceBit :: i -> Bit -> a -> a
replaceBit i :: i
i b :: Bit
b v :: a
v = BitVector (BitSize a) -> a
forall a. BitPack a => BitVector (BitSize a) -> a
unpack (BitVector (BitSize a) -> Int -> Bit -> BitVector (BitSize a)
forall (n :: Nat).
KnownNat n =>
BitVector n -> Int -> Bit -> BitVector n
replaceBit# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v) (i -> Int
forall a. Enum a => a -> Int
fromEnum i
i) Bit
b)
{-# INLINE setSlice #-}
setSlice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n
-> BitVector (m + 1 - n) -> a -> a
setSlice :: SNat m -> SNat n -> BitVector ((m + 1) - n) -> a -> a
setSlice m :: SNat m
m n :: SNat n
n w :: BitVector ((m + 1) - n)
w v :: a
v = BitVector (BitSize a) -> a
forall a. BitPack a => BitVector (BitSize a) -> a
unpack (BitVector ((m + 1) + i)
-> SNat m
-> SNat n
-> BitVector ((m + 1) - n)
-> BitVector ((m + 1) + i)
forall (m :: Nat) (i :: Nat) (n :: Nat).
BitVector ((m + 1) + i)
-> SNat m
-> SNat n
-> BitVector ((m + 1) - n)
-> BitVector ((m + 1) + i)
setSlice# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v) SNat m
m SNat n
n BitVector ((m + 1) - n)
w)
{-# INLINE msb #-}
msb :: (BitPack a, KnownNat (BitSize a)) => a -> Bit
msb :: a -> Bit
msb v :: a
v = BitVector (BitSize a) -> Bit
forall (n :: Nat). KnownNat n => BitVector n -> Bit
msb# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v)
{-# INLINE lsb #-}
lsb :: BitPack a => a -> Bit
lsb :: a -> Bit
lsb v :: a
v = BitVector (BitSize a) -> Bit
forall (n :: Nat). BitVector n -> Bit
lsb# (a -> BitVector (BitSize a)
forall a. BitPack a => a -> BitVector (BitSize a)
pack a
v)