    {-|
    Copyright  :  (C) 2013-2016, University of Twente,
                      2016     , Myrtle Software Ltd,
                      2021-2024, QBayLogic B.V.
    License    :  BSD2 (see the file LICENSE)
    Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveAnyClass #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE MultiWayIf #-}
    {-# LANGUAGE RoleAnnotations #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE UndecidableInstances #-}

    {-# LANGUAGE Unsafe #-}

    {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
    {-# OPTIONS_HADDOCK show-extensions not-home #-}

    module Clash.Sized.Internal.Unsigned
      ( -- * Datatypes
        Unsigned (..)
        -- * Accessors
        -- ** Length information
      , size#
        -- * Type classes
        -- ** BitPack
      , pack#
      , unpack#
        -- ** Eq
      , eq#
      , neq#
        -- ** Ord
      , lt#
      , ge#
      , gt#
      , le#
        -- ** Enum
      , toEnum#
      , fromEnum#
        -- ** Enum (not synthesizable)
      , enumFrom#
      , enumFromThen#
      , enumFromTo#
      , enumFromThenTo#
        -- ** Bounded
      , minBound#
      , maxBound#
        -- ** Num
      , (+#)
      , (-#)
      , (*#)
      , negate#
      , fromInteger#
        -- ** ExtendingNum
      , plus#
      , minus#
      , times#
        -- ** Integral
      , quot#
      , rem#
      , toInteger#
        -- ** Bits
      , and#
      , or#
      , xor#
      , complement#
      , shiftL#
      , shiftR#
      , rotateL#
      , rotateR#
        -- ** Resize
      , resize#
        -- ** Conversions
      , unsignedToWord
      , unsigned8toWord8
      , unsigned16toWord16
      , unsigned32toWord32
      )
    where

    import Prelude hiding                 (even, odd)

    import Control.DeepSeq                (NFData (..))
    import Control.Lens                   (Index, Ixed (..), IxValue)
    import Data.Bits                      (Bits (..), FiniteBits (..))
    import Data.Data                      (Data)
    import Data.Default.Class             (Default (..))
    import Data.Proxy                     (Proxy (..))
    import Text.Read                      (Read (..), ReadPrec)
    import Text.Printf                    (PrintfArg (..), printf)
    #if MIN_VERSION_base(4,16,0)
    import GHC.Exts                       (wordToWord8#, wordToWord16#, wordToWord32#)
    #else
    import GHC.Exts                       (narrow8Word#, narrow16Word#, narrow32Word#)
    #endif
    import GHC.Generics                   (Generic)
    #if MIN_VERSION_base(4,15,0)
    import GHC.Num.BigNat                 (bigNatToWord, bigNatToWord#)
    import GHC.Num.Integer
      (integerFromNatural, integerShiftL, integerToNatural)
    import GHC.Num.Natural
      (Natural (..), naturalShiftL, naturalShiftR, naturalToWord)
    #else
    import GHC.Integer.GMP.Internals      (bigNatToWord)
    import GHC.Natural                    (Natural (..), naturalFromInteger)
    #endif
    import GHC.Natural                    (naturalToInteger)
    import GHC.TypeLits                   (KnownNat, Nat, type (+))
    #if MIN_VERSION_base(4,15,0)
    import GHC.TypeNats                   (natVal)
    #else
    import GHC.TypeLits                   (natVal)
    #endif
    import GHC.TypeLits.Extra             (Max)
    import GHC.Word                       (Word (..), Word8 (..), Word16 (..), Word32 (..))
    import Data.Ix                        (Ix(..))
    import Language.Haskell.TH            (appT, conT, litT, numTyLit, sigE)
    import Language.Haskell.TH.Syntax     (Lift(..))
    #if MIN_VERSION_template_haskell(2,16,0)
    import Language.Haskell.TH.Compat
    #endif
    #if MIN_VERSION_template_haskell(2,17,0)
    import Language.Haskell.TH            (Quote, Type)
    #else
    import Language.Haskell.TH            (TypeQ)
    #endif
    import Test.QuickCheck.Arbitrary      (Arbitrary (..), CoArbitrary (..),
                                           arbitraryBoundedIntegral,
                                           coarbitraryIntegral)

    import Clash.Annotations.Primitive (hasBlackBox)
    import Clash.Class.BitPack            (BitPack (..), packXWith, bitCoerce)
    import Clash.Class.Num                (ExtendingNum (..), SaturatingNum (..),
                                           SaturationMode (..))
    import Clash.Class.Parity             (Parity (..))
    import Clash.Class.Resize             (Resize (..))
    import Clash.Class.BitPack.BitIndex   ((!), msb, replaceBit, split)
    import Clash.Class.BitPack.BitReduction (reduceOr)
    import Clash.Promoted.Nat             (natToNum, natToNatural)
    import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, high, low, undefError)
    import qualified Clash.Sized.Internal.BitVector as BV
    import Clash.Sized.Internal.Mod
    import Clash.XException
      (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)

    {- $setup
    >>> :m -Prelude
    >>> import Clash.Prelude
    -}

    #include "MachDeps.h"

    type role Unsigned nominal

    -- | Arbitrary-width unsigned integer represented by @n@ bits
    --
    -- Given @n@ bits, an 'Unsigned' @n@ number has a range of: [0 .. 2^@n@-1]
    --
    -- * __NB__: The usual Haskell method of converting an integral numeric type to
    -- another, 'fromIntegral', is not well suited for Clash as it will go through
    -- 'Integer' which is arbitrarily bounded in HDL. Instead use
    -- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
    -- * __NB__: The 'Num' operators perform @wrap-around@ on overflow. If you want
    -- saturation on overflow, check out the 'SaturatingNum' class.
    --
    -- >>> maxBound :: Unsigned 3
    -- 7
    -- >>> minBound :: Unsigned 3
    -- 0
    -- >>> read (show (maxBound :: Unsigned 3)) :: Unsigned 3
    -- 7
    -- >>> 1 + 2 :: Unsigned 3
    -- 3
    -- >>> 2 + 6 :: Unsigned 3
    -- 0
    -- >>> 1 - 3 :: Unsigned 3
    -- 6
    -- >>> 2 * 3 :: Unsigned 3
    -- 6
    -- >>> 2 * 4 :: Unsigned 3
    -- 0
    -- >>> (2 :: Unsigned 3) `mul` (4 :: Unsigned 3) :: Unsigned 6
    -- 8
    -- >>> (2 :: Unsigned 3) `add` (6 :: Unsigned 3) :: Unsigned 4
    -- 8
    -- >>> satAdd SatSymmetric 2 6 :: Unsigned 3
    -- 7
    -- >>> satSub SatSymmetric 2 3 :: Unsigned 3
    -- 0
    --
    -- Unsigned has the <https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/roles.html type role>
    --
    -- >>> :i Unsigned
    -- type role Unsigned nominal
    -- ...
    --
    -- as it is not safe to coerce between different width Unsigned. To change the
    -- width, use the functions in the 'Clash.Class.Resize.Resize' class.
    data Unsigned (n :: Nat) =
        -- | The constructor, 'U', and the field, 'unsafeToNatural', are not
        -- synthesizable.
        U { forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural :: !Natural }
      deriving (Typeable (Unsigned n)
    Typeable (Unsigned n) =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n))
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (Unsigned n))
    -> (Unsigned n -> Constr)
    -> (Unsigned n -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n)))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (Unsigned n)))
    -> ((forall b. Data b => b -> b) -> Unsigned n -> Unsigned n)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Unsigned n -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
    -> Data (Unsigned n)
    Unsigned n -> Constr
    Unsigned n -> DataType
    (forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
    forall (n :: Nat). KnownNat n => Typeable (Unsigned n)
    forall (n :: Nat). KnownNat n => Unsigned n -> Constr
    forall (n :: Nat). KnownNat n => Unsigned n -> DataType
    forall (n :: Nat).
    KnownNat n =>
    (forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
    forall (n :: Nat) u.
    KnownNat n =>
    Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
    forall (n :: Nat) u.
    KnownNat n =>
    (forall d. Data d => d -> u) -> Unsigned n -> [u]
    forall (n :: Nat) r r'.
    KnownNat n =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    forall (n :: Nat) r r'.
    KnownNat n =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    forall (n :: Nat) (m :: Type -> Type).
    (KnownNat n, Monad m) =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    forall (n :: Nat) (m :: Type -> Type).
    (KnownNat n, MonadPlus m) =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    forall (n :: Nat) (c :: Type -> Type).
    KnownNat n =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Unsigned n)
    forall (n :: Nat) (c :: Type -> Type).
    KnownNat n =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n)
    forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
    (KnownNat n, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
    forall (n :: Nat) (t :: Type -> Type -> Type) (c :: Type -> Type).
    (KnownNat n, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Unsigned n))
    forall a.
    Typeable a =>
    (forall (c :: Type -> Type).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: Type -> Type).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: Type -> Type).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: Type -> Type).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
    forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Unsigned n)
    forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n)
    forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
    forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Unsigned n))
    $cgfoldl :: forall (n :: Nat) (c :: Type -> Type).
    KnownNat n =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n)
    gfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n)
    $cgunfold :: forall (n :: Nat) (c :: Type -> Type).
    KnownNat n =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Unsigned n)
    gunfold :: forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Unsigned n)
    $ctoConstr :: forall (n :: Nat). KnownNat n => Unsigned n -> Constr
    toConstr :: Unsigned n -> Constr
    $cdataTypeOf :: forall (n :: Nat). KnownNat n => Unsigned n -> DataType
    dataTypeOf :: Unsigned n -> DataType
    $cdataCast1 :: forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
    (KnownNat n, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
    dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
    $cdataCast2 :: forall (n :: Nat) (t :: Type -> Type -> Type) (c :: Type -> Type).
    (KnownNat n, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Unsigned n))
    dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Unsigned n))
    $cgmapT :: forall (n :: Nat).
    KnownNat n =>
    (forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
    gmapT :: (forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
    $cgmapQl :: forall (n :: Nat) r r'.
    KnownNat n =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    $cgmapQr :: forall (n :: Nat) r r'.
    KnownNat n =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
    $cgmapQ :: forall (n :: Nat) u.
    KnownNat n =>
    (forall d. Data d => d -> u) -> Unsigned n -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u]
    $cgmapQi :: forall (n :: Nat) u.
    KnownNat n =>
    Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
    $cgmapM :: forall (n :: Nat) (m :: Type -> Type).
    (KnownNat n, Monad m) =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    gmapM :: forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    $cgmapMp :: forall (n :: Nat) (m :: Type -> Type).
    (KnownNat n, MonadPlus m) =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    gmapMp :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    $cgmapMo :: forall (n :: Nat) (m :: Type -> Type).
    (KnownNat n, MonadPlus m) =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    gmapMo :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
    Data, (forall x. Unsigned n -> Rep (Unsigned n) x)
    -> (forall x. Rep (Unsigned n) x -> Unsigned n)
    -> Generic (Unsigned n)
    forall (n :: Nat) x. Rep (Unsigned n) x -> Unsigned n
    forall (n :: Nat) x. Unsigned n -> Rep (Unsigned n) x
    forall x. Rep (Unsigned n) x -> Unsigned n
    forall x. Unsigned n -> Rep (Unsigned n) x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall (n :: Nat) x. Unsigned n -> Rep (Unsigned n) x
    from :: forall x. Unsigned n -> Rep (Unsigned n) x
    $cto :: forall (n :: Nat) x. Rep (Unsigned n) x -> Unsigned n
    to :: forall x. Rep (Unsigned n) x -> Unsigned n
    Generic)

    {-# ANN U hasBlackBox #-}

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE size# #-}
    {-# ANN size# hasBlackBox #-}
    size# :: KnownNat n => Unsigned n -> Int
    #if MIN_VERSION_base(4,15,0)
    size# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int
    size# Unsigned n
    u = Nat -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Unsigned n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal Unsigned n
    u)
    #else
    size# u = fromInteger (natVal u)
    #endif

    instance NFData (Unsigned n) where
      rnf :: Unsigned n -> ()
    rnf (U Nat
    i) = Nat -> ()
    forall a. NFData a => a -> ()
    rnf Nat
    i () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()
      {-# NOINLINE rnf #-}
      -- NOINLINE is needed so that Clash doesn't trip on the "Unsigned ~# Natural"
      -- coercion

    instance Show (Unsigned n) where
      show :: Unsigned n -> String
    show (U Nat
    i) = Nat -> String
    forall a. Show a => a -> String
    show Nat
    i
      {-# NOINLINE show #-}

    instance ShowX (Unsigned n) where
      showsPrecX :: Int -> Unsigned n -> ShowS
    showsPrecX = (Int -> Unsigned n -> ShowS) -> Int -> Unsigned n -> ShowS
    forall a. (Int -> a -> ShowS) -> Int -> a -> ShowS
    showsPrecXWith Int -> Unsigned n -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec

    instance NFDataX (Unsigned n) where
      deepErrorX :: HasCallStack => String -> Unsigned n
    deepErrorX = String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX
      ensureSpine :: Unsigned n -> Unsigned n
    ensureSpine = Unsigned n -> Unsigned n
    forall a. a -> a
    id
      rnfX :: Unsigned n -> ()
    rnfX = Unsigned n -> ()
    forall a. a -> ()
    rwhnfX

    -- | None of the 'Read' class' methods are synthesizable.
    instance KnownNat n => Read (Unsigned n) where
      readPrec :: ReadPrec (Unsigned n)
    readPrec = Nat -> Unsigned n
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Nat -> Unsigned n) -> ReadPrec Nat -> ReadPrec (Unsigned n)
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ReadPrec Nat
    forall a. Read a => ReadPrec a
    readPrec :: ReadPrec Natural)

    instance KnownNat n => BitPack (Unsigned n) where
      type BitSize (Unsigned n) = n
      pack :: Unsigned n -> BitVector (BitSize (Unsigned n))
    pack   = (Unsigned n -> BitVector n) -> Unsigned n -> BitVector n
    forall (n :: Nat) a.
    KnownNat n =>
    (a -> BitVector n) -> a -> BitVector n
    packXWith Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack#
      unpack :: BitVector (BitSize (Unsigned n)) -> Unsigned n
    unpack = BitVector n -> Unsigned n
    BitVector (BitSize (Unsigned n)) -> Unsigned n
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack#

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE pack# #-}
    {-# ANN pack# hasBlackBox #-}
    pack# :: Unsigned n -> BitVector n
    pack# :: forall (n :: Nat). Unsigned n -> BitVector n
    pack# (U Nat
    i) = Nat -> Nat -> BitVector n
    forall (n :: Nat). Nat -> Nat -> BitVector n
    BV Nat
    0 Nat
    i

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE unpack# #-}
    {-# ANN unpack# hasBlackBox #-}
    unpack# :: KnownNat n => BitVector n -> Unsigned n
    unpack# :: forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# (BV Nat
    0 Nat
    i) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U Nat
    i
    unpack# BitVector n
    bv = String -> [BitVector n] -> Unsigned n
    forall (n :: Nat) a. KnownNat n => String -> [BitVector n] -> a
    undefError String
    "Unsigned.unpack" [BitVector n
    bv]

    instance Eq (Unsigned n) where
      == :: Unsigned n -> Unsigned n -> Bool
    (==) = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    eq#
      /= :: Unsigned n -> Unsigned n -> Bool
    (/=) = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    neq#

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE eq# #-}
    {-# ANN eq# hasBlackBox #-}
    eq# :: Unsigned n -> Unsigned n -> Bool
    eq# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    eq# (U Nat
    v1) (U Nat
    v2) = Nat
    v1 Nat -> Nat -> Bool
    forall a. Eq a => a -> a -> Bool
    == Nat
    v2

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE neq# #-}
    {-# ANN neq# hasBlackBox #-}
    neq# :: Unsigned n -> Unsigned n -> Bool
    neq# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    neq# (U Nat
    v1) (U Nat
    v2) = Nat
    v1 Nat -> Nat -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Nat
    v2

    instance Ord (Unsigned n) where
      < :: Unsigned n -> Unsigned n -> Bool
    (<)  = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    lt#
      >= :: Unsigned n -> Unsigned n -> Bool
    (>=) = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    ge#
      > :: Unsigned n -> Unsigned n -> Bool
    (>)  = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    gt#
      <= :: Unsigned n -> Unsigned n -> Bool
    (<=) = Unsigned n -> Unsigned n -> Bool
    forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    le#

    lt#,ge#,gt#,le# :: Unsigned n -> Unsigned n -> Bool
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE lt# #-}
    {-# ANN lt# hasBlackBox #-}
    lt# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    lt# (U Nat
    n) (U Nat
    m) = Nat
    n Nat -> Nat -> Bool
    forall a. Ord a => a -> a -> Bool
    < Nat
    m
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE ge# #-}
    {-# ANN ge# hasBlackBox #-}
    ge# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    ge# (U Nat
    n) (U Nat
    m) = Nat
    n Nat -> Nat -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Nat
    m
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE gt# #-}
    {-# ANN gt# hasBlackBox #-}
    gt# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    gt# (U Nat
    n) (U Nat
    m) = Nat
    n Nat -> Nat -> Bool
    forall a. Ord a => a -> a -> Bool
    > Nat
    m
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE le# #-}
    {-# ANN le# hasBlackBox #-}
    le# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
    le# (U Nat
    n) (U Nat
    m) = Nat
    n Nat -> Nat -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Nat
    m

    -- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and
    -- 'enumFromThenTo', are not synthesizable.
    instance KnownNat n => Enum (Unsigned n) where
      succ :: Unsigned n -> Unsigned n
    succ Unsigned n
    n
        | Unsigned n
    n Unsigned n -> Unsigned n -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unsigned n
    forall a. Bounded a => a
    maxBound =
            String -> Unsigned n
    forall a. HasCallStack => String -> a
    error (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'succ' was called on (" String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> forall a. Show a => a -> String
    show @(Unsigned n) Unsigned n
    forall a. Bounded a => a
    maxBound String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    " :: "
                 String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    "Unsigned " String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Nat -> String
    forall a. Show a => a -> String
    show (forall (n :: Nat). KnownNat n => Nat
    natToNatural @n) String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    ") and caused an "
                 String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    "overflow. Use 'satSucc' and specify a SaturationMode if you "
                 String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    "need other behavior."
        | Bool
    otherwise = Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    +# Integer -> Unsigned n
    forall (n :: Nat). KnownNat n => Integer -> Unsigned n
    fromInteger# Integer
    1

      pred :: Unsigned n -> Unsigned n
    pred Unsigned n
    n
        | Unsigned n
    n Unsigned n -> Unsigned n -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unsigned n
    forall a. Bounded a => a
    minBound =
            String -> Unsigned n
    forall a. HasCallStack => String -> a
    error (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'pred' was called on (0 :: Unsigned " String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Nat -> String
    forall a. Show a => a -> String
    show (forall (n :: Nat). KnownNat n => Nat
    natToNatural @n)
                 String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    ") and caused an overflow. Use 'satPred' and specify a "
                 String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    "SaturationMode if you need other behavior."
        | Bool
    otherwise = Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    -# Integer -> Unsigned n
    forall (n :: Nat). KnownNat n => Integer -> Unsigned n
    fromInteger# Integer
    1

      toEnum :: Int -> Unsigned n
    toEnum         = Int -> Unsigned n
    forall (n :: Nat). KnownNat n => Int -> Unsigned n
    toEnum#
      fromEnum :: Unsigned n -> Int
    fromEnum       = Unsigned n -> Int
    forall (n :: Nat). KnownNat n => Unsigned n -> Int
    fromEnum#
      enumFrom :: Unsigned n -> [Unsigned n]
    enumFrom       = Unsigned n -> [Unsigned n]
    forall (n :: Nat). KnownNat n => Unsigned n -> [Unsigned n]
    enumFrom#
      enumFromThen :: Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThen   = Unsigned n -> Unsigned n -> [Unsigned n]
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThen#
      enumFromTo :: Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromTo     = Unsigned n -> Unsigned n -> [Unsigned n]
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromTo#
      enumFromThenTo :: Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThenTo = Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThenTo#

    toEnum# :: forall n. KnownNat n => Int -> Unsigned n
    toEnum# :: forall (n :: Nat). KnownNat n => Int -> Unsigned n
    toEnum# = Integer -> Unsigned n
    forall (n :: Nat). KnownNat n => Integer -> Unsigned n
    fromInteger# (Integer -> Unsigned n) -> (Int -> Integer) -> Int -> Unsigned n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE toEnum# #-}
    {-# ANN toEnum# hasBlackBox #-}

    fromEnum# :: forall n. KnownNat n => Unsigned n -> Int
    fromEnum# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int
    fromEnum# = Integer -> Int
    forall a. Enum a => a -> Int
    fromEnum (Integer -> Int) -> (Unsigned n -> Integer) -> Unsigned n -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unsigned n -> Integer
    forall (n :: Nat). Unsigned n -> Integer
    toInteger#
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE fromEnum# #-}
    {-# ANN fromEnum# hasBlackBox #-}

    enumFrom# :: forall n. KnownNat n => Unsigned n -> [Unsigned n]
    enumFrom# :: forall (n :: Nat). KnownNat n => Unsigned n -> [Unsigned n]
    enumFrom# = \Unsigned n
    x -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
    forall a b. (a -> b) -> [a] -> [b]
    map (Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)) [Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    x .. Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural (Unsigned n
    forall a. Bounded a => a
    maxBound :: Unsigned n)]
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE enumFrom# #-}

    enumFromThen# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThen# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThen# = \Unsigned n
    x Unsigned n
    y -> [Nat] -> [Unsigned n]
    toUnsigneds [Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    x, Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    y .. Unsigned n -> Unsigned n -> Nat
    bound Unsigned n
    x Unsigned n
    y]
     where
      toUnsigneds :: [Nat] -> [Unsigned n]
    toUnsigneds = (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
    forall a b. (a -> b) -> [a] -> [b]
    map (Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m))
      bound :: Unsigned n -> Unsigned n -> Nat
    bound Unsigned n
    x Unsigned n
    y = Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural (if Unsigned n
    x Unsigned n -> Unsigned n -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Unsigned n
    y then Unsigned n
    forall a. Bounded a => a
    maxBound else Unsigned n
    forall a. Bounded a => a
    minBound :: Unsigned n)
    #if MIN_VERSION_base(4,15,0)
      m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE enumFromThen# #-}

    enumFromTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromTo# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromTo# = \Unsigned n
    x Unsigned n
    y -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
    forall a b. (a -> b) -> [a] -> [b]
    map (Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)) [Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    x .. Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    y]
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE enumFromTo# #-}

    enumFromThenTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThenTo# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
    enumFromThenTo# = \Unsigned n
    x1 Unsigned n
    x2 Unsigned n
    y -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
    forall a b. (a -> b) -> [a] -> [b]
    map (Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)) [Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    x1, Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    x2 .. Unsigned n -> Nat
    forall (n :: Nat). Unsigned n -> Nat
    unsafeToNatural Unsigned n
    y]
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE enumFromThenTo# #-}

    instance KnownNat n => Bounded (Unsigned n) where
      minBound :: Unsigned n
    minBound = Unsigned n
    forall (n :: Nat). Unsigned n
    minBound#
      maxBound :: Unsigned n
    maxBound = Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n
    maxBound#

    minBound# :: Unsigned n
    minBound# :: forall (n :: Nat). Unsigned n
    minBound# = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U Nat
    0
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE minBound# #-}
    {-# ANN minBound# hasBlackBox #-}

    maxBound# :: forall n. KnownNat n => Unsigned n
    maxBound# :: forall (n :: Nat). KnownNat n => Unsigned n
    maxBound# = let m :: Nat
    m = Nat
    1 Nat -> Int -> Nat
    forall a. Bits a => a -> Int -> a
    `shiftL` (forall (n :: Nat) a. (Num a, KnownNat n) => a
    natToNum @n) in  Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    m Nat -> Nat -> Nat
    forall a. Num a => a -> a -> a
    - Nat
    1)
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE maxBound# #-}
    {-# ANN maxBound# hasBlackBox #-}

    -- | __NB__: 'fromInteger'/'fromIntegral' can cause unexpected truncation, as
    -- 'Integer' is arbitrarily bounded during synthesis.  Prefer
    -- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
    instance KnownNat n => Num (Unsigned n) where
      + :: Unsigned n -> Unsigned n -> Unsigned n
    (+)         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (+#)
      (-)         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (-#)
      * :: Unsigned n -> Unsigned n -> Unsigned n
    (*)         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (*#)
      negate :: Unsigned n -> Unsigned n
    negate      = Unsigned n -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
    negate#
      abs :: Unsigned n -> Unsigned n
    abs         = Unsigned n -> Unsigned n
    forall a. a -> a
    id
      signum :: Unsigned n -> Unsigned n
    signum Unsigned n
    bv   = Unsigned 1 -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# (BitVector 1 -> Unsigned 1
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# (Bit -> BitVector 1
    BV.pack# (Unsigned n -> Bit
    forall a. BitPack a => a -> Bit
    reduceOr Unsigned n
    bv)))
      fromInteger :: Integer -> Unsigned n
    fromInteger = Integer -> Unsigned n
    forall (n :: Nat). KnownNat n => Integer -> Unsigned n
    fromInteger#

    (+#),(-#),(*#) :: forall n . KnownNat n => Unsigned n -> Unsigned n -> Unsigned n
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE (+#) #-}
    {-# ANN (+#) hasBlackBox #-}
    +# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (+#) = \(U Nat
    i) (U Nat
    j) -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat -> Nat -> Nat
    addMod Nat
    m Nat
    i Nat
    j)
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE (-#) #-}
    {-# ANN (-#) hasBlackBox #-}
    -# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (-#) = \(U Nat
    i) (U Nat
    j) -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat -> Nat -> Nat
    subMod Nat
    m Nat
    i Nat
    j)
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE (*#) #-}
    {-# ANN (*#) hasBlackBox #-}
    *# :: forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    (*#) = \(U Nat
    i) (U Nat
    j) -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat -> Nat -> Nat
    mulMod2 Nat
    m Nat
    i Nat
    j)
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = (Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))) Nat -> Nat -> Nat
    forall a. Num a => a -> a -> a
    - Nat
    1
    #else
      where m = (1 `shiftL` fromInteger (natVal (Proxy @n))) - 1
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE negate# #-}
    {-# ANN negate# hasBlackBox #-}
    negate# :: forall n . KnownNat n => Unsigned n -> Unsigned n
    negate# :: forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
    negate# = \(U Nat
    i) -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat -> Nat
    negateMod Nat
    m Nat
    i)
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE fromInteger# #-}
    {-# ANN fromInteger# hasBlackBox #-}
    fromInteger# :: forall n . KnownNat n => Integer -> Unsigned n
    #if MIN_VERSION_base(4,15,0)
    fromInteger# :: forall (n :: Nat). KnownNat n => Integer -> Unsigned n
    fromInteger# = \Integer
    x -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Integer -> Nat
    integerToNatural (Integer
    x Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `mod` Integer
    m))
     where
      m :: Integer
    m = Integer
    1 Integer -> Word -> Integer
    `integerShiftL` Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
    #else
    fromInteger# = \x -> U (naturalFromInteger (x `mod` m))
     where
      m = 1 `shiftL` fromInteger (natVal (Proxy @n))
    #endif

    instance (KnownNat m, KnownNat n) => ExtendingNum (Unsigned m) (Unsigned n) where
      type AResult (Unsigned m) (Unsigned n) = Unsigned (Max m n + 1)
      add :: Unsigned m -> Unsigned n -> AResult (Unsigned m) (Unsigned n)
    add  = Unsigned m -> Unsigned n -> AResult (Unsigned m) (Unsigned n)
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus#
      sub :: Unsigned m -> Unsigned n -> AResult (Unsigned m) (Unsigned n)
    sub = Unsigned m -> Unsigned n -> AResult (Unsigned m) (Unsigned n)
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    forall (m :: Nat) (n :: Nat).
    (KnownNat m, KnownNat n) =>
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    minus#
      type MResult (Unsigned m) (Unsigned n) = Unsigned (m + n)
      mul :: Unsigned m -> Unsigned n -> MResult (Unsigned m) (Unsigned n)
    mul = Unsigned m -> Unsigned n -> MResult (Unsigned m) (Unsigned n)
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    times#

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE plus# #-}
    {-# ANN plus# hasBlackBox #-}
    plus# :: Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus# :: forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus# (U Nat
    a) (U Nat
    b) = Nat -> Unsigned (Max m n + 1)
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    a Nat -> Nat -> Nat
    forall a. Num a => a -> a -> a
    + Nat
    b)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE minus# #-}
    {-# ANN minus# hasBlackBox #-}
    minus# :: forall m n . (KnownNat m, KnownNat n) => Unsigned m -> Unsigned n
                                                    -> Unsigned (Max m n + 1)
    minus# :: forall (m :: Nat) (n :: Nat).
    (KnownNat m, KnownNat n) =>
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    minus# = \(U Nat
    a) (U Nat
    b) -> Nat -> Unsigned (Max m n + 1)
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat -> Nat -> Nat
    subMod Nat
    mask Nat
    a Nat
    b)
     where
    #if MIN_VERSION_base(4,15,0)
      sz :: Word
    sz   = Nat -> Word
    naturalToWord (Proxy (Max m n + 1) -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(Max m n + 1)))
      mask :: Nat
    mask = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Word
    sz
    #else
      sz   = fromInteger (natVal (Proxy @(Max m n + 1)))
      mask = 1 `shiftL` sz
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE times# #-}
    {-# ANN times# hasBlackBox #-}
    times# :: Unsigned m -> Unsigned n -> Unsigned (m + n)
    times# :: forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    times# (U Nat
    a) (U Nat
    b) = Nat -> Unsigned (m + n)
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    a Nat -> Nat -> Nat
    forall a. Num a => a -> a -> a
    * Nat
    b)

    instance KnownNat n => Real (Unsigned n) where
      toRational :: Unsigned n -> Rational
    toRational = Integer -> Rational
    forall a. Real a => a -> Rational
    toRational (Integer -> Rational)
    -> (Unsigned n -> Integer) -> Unsigned n -> Rational
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unsigned n -> Integer
    forall (n :: Nat). Unsigned n -> Integer
    toInteger#

    -- | __NB__: 'toInteger'/'fromIntegral' can cause unexpected truncation, as
    -- 'Integer' is arbitrarily bounded during synthesis.  Prefer
    -- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
    instance KnownNat n => Integral (Unsigned n) where
      quot :: Unsigned n -> Unsigned n -> Unsigned n
    quot        = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    quot#
      rem :: Unsigned n -> Unsigned n -> Unsigned n
    rem         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    rem#
      div :: Unsigned n -> Unsigned n -> Unsigned n
    div         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    quot#
      mod :: Unsigned n -> Unsigned n -> Unsigned n
    mod         = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    rem#
      quotRem :: Unsigned n -> Unsigned n -> (Unsigned n, Unsigned n)
    quotRem Unsigned n
    n Unsigned n
    d = (Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    `quot#` Unsigned n
    d,Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    `rem#` Unsigned n
    d)
      divMod :: Unsigned n -> Unsigned n -> (Unsigned n, Unsigned n)
    divMod  Unsigned n
    n Unsigned n
    d = (Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    `quot#` Unsigned n
    d,Unsigned n
    n Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    `rem#` Unsigned n
    d)
      toInteger :: Unsigned n -> Integer
    toInteger   = Unsigned n -> Integer
    forall (n :: Nat). Unsigned n -> Integer
    toInteger#

    quot#,rem# :: Unsigned n -> Unsigned n -> Unsigned n
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE quot# #-}
    {-# ANN quot# hasBlackBox #-}
    quot# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    quot# (U Nat
    i) (U Nat
    j) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    i Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `quot` Nat
    j)
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE rem# #-}
    {-# ANN rem# hasBlackBox #-}
    rem# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    rem# (U Nat
    i) (U Nat
    j) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    i Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `rem` Nat
    j)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE toInteger# #-}
    {-# ANN toInteger# hasBlackBox #-}
    toInteger# :: Unsigned n -> Integer
    toInteger# :: forall (n :: Nat). Unsigned n -> Integer
    toInteger# (U Nat
    i) = Nat -> Integer
    naturalToInteger Nat
    i

    instance KnownNat n => PrintfArg (Unsigned n) where
      formatArg :: Unsigned n -> FieldFormatter
    formatArg = Integer -> FieldFormatter
    forall a. PrintfArg a => a -> FieldFormatter
    formatArg (Integer -> FieldFormatter)
    -> (Unsigned n -> Integer) -> Unsigned n -> FieldFormatter
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unsigned n -> Integer
    forall a. Integral a => a -> Integer
    toInteger

    instance KnownNat n => Parity (Unsigned n) where
      even :: Unsigned n -> Bool
    even = BitVector n -> Bool
    forall a. Parity a => a -> Bool
    even (BitVector n -> Bool)
    -> (Unsigned n -> BitVector n) -> Unsigned n -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unsigned n -> BitVector n
    Unsigned n -> BitVector (BitSize (Unsigned n))
    forall a. BitPack a => a -> BitVector (BitSize a)
    pack
      odd :: Unsigned n -> Bool
    odd = BitVector n -> Bool
    forall a. Parity a => a -> Bool
    odd (BitVector n -> Bool)
    -> (Unsigned n -> BitVector n) -> Unsigned n -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unsigned n -> BitVector n
    Unsigned n -> BitVector (BitSize (Unsigned n))
    forall a. BitPack a => a -> BitVector (BitSize a)
    pack

    instance KnownNat n => Bits (Unsigned n) where
      .&. :: Unsigned n -> Unsigned n -> Unsigned n
    (.&.)             = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    and#
      .|. :: Unsigned n -> Unsigned n -> Unsigned n
    (.|.)             = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    or#
      xor :: Unsigned n -> Unsigned n -> Unsigned n
    xor               = Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    xor#
      complement :: Unsigned n -> Unsigned n
    complement        = Unsigned n -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
    complement#
      zeroBits :: Unsigned n
    zeroBits          = Unsigned n
    0
      bit :: Int -> Unsigned n
    bit Int
    i             = Int -> Bit -> Unsigned n -> Unsigned n
    forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
    replaceBit Int
    i Bit
    high Unsigned n
    0
      setBit :: Unsigned n -> Int -> Unsigned n
    setBit Unsigned n
    v Int
    i        = Int -> Bit -> Unsigned n -> Unsigned n
    forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
    replaceBit Int
    i Bit
    high Unsigned n
    v
      clearBit :: Unsigned n -> Int -> Unsigned n
    clearBit Unsigned n
    v Int
    i      = Int -> Bit -> Unsigned n -> Unsigned n
    forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
    replaceBit Int
    i Bit
    low  Unsigned n
    v
      complementBit :: Unsigned n -> Int -> Unsigned n
    complementBit Unsigned n
    v Int
    i = Int -> Bit -> Unsigned n -> Unsigned n
    forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
    replaceBit Int
    i (Bit -> Bit
    BV.complement## (Unsigned n
    v Unsigned n -> Int -> Bit
    forall a i. (BitPack a, Enum i) => a -> i -> Bit
    ! Int
    i)) Unsigned n
    v
      testBit :: Unsigned n -> Int -> Bool
    testBit Unsigned n
    v Int
    i       = Unsigned n
    v Unsigned n -> Int -> Bit
    forall a i. (BitPack a, Enum i) => a -> i -> Bit
    ! Int
    i Bit -> Bit -> Bool
    forall a. Eq a => a -> a -> Bool
    == Bit
    high
      bitSizeMaybe :: Unsigned n -> Maybe Int
    bitSizeMaybe Unsigned n
    v    = Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Unsigned n -> Int
    forall (n :: Nat). KnownNat n => Unsigned n -> Int
    size# Unsigned n
    v)
      bitSize :: Unsigned n -> Int
    bitSize           = Unsigned n -> Int
    forall (n :: Nat). KnownNat n => Unsigned n -> Int
    size#
      isSigned :: Unsigned n -> Bool
    isSigned Unsigned n
    _        = Bool
    False
      shiftL :: Unsigned n -> Int -> Unsigned n
    shiftL Unsigned n
    v Int
    i        = Unsigned n -> Int -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    shiftL# Unsigned n
    v Int
    i
      shiftR :: Unsigned n -> Int -> Unsigned n
    shiftR Unsigned n
    v Int
    i        = Unsigned n -> Int -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    shiftR# Unsigned n
    v Int
    i
      rotateL :: Unsigned n -> Int -> Unsigned n
    rotateL Unsigned n
    v Int
    i       = Unsigned n -> Int -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    rotateL# Unsigned n
    v Int
    i
      rotateR :: Unsigned n -> Int -> Unsigned n
    rotateR Unsigned n
    v Int
    i       = Unsigned n -> Int -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    rotateR# Unsigned n
    v Int
    i
      popCount :: Unsigned n -> Int
    popCount Unsigned n
    u        = BitVector n -> Int
    forall a. Bits a => a -> Int
    popCount (Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack# Unsigned n
    u)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE and# #-}
    {-# ANN and# hasBlackBox #-}
    and# :: Unsigned n -> Unsigned n -> Unsigned n
    and# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    and# (U Nat
    v1) (U Nat
    v2) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    v1 Nat -> Nat -> Nat
    forall a. Bits a => a -> a -> a
    .&. Nat
    v2)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE or# #-}
    {-# ANN or# hasBlackBox #-}
    or# :: Unsigned n -> Unsigned n -> Unsigned n
    or# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    or# (U Nat
    v1) (U Nat
    v2) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    v1 Nat -> Nat -> Nat
    forall a. Bits a => a -> a -> a
    .|. Nat
    v2)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE xor# #-}
    {-# ANN xor# hasBlackBox #-}
    xor# :: Unsigned n -> Unsigned n -> Unsigned n
    xor# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
    xor# (U Nat
    v1) (U Nat
    v2) = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    v1 Nat -> Nat -> Nat
    forall a. Bits a => a -> a -> a
    `xor` Nat
    v2)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE complement# #-}
    {-# ANN complement# hasBlackBox #-}
    complement# :: forall n . KnownNat n => Unsigned n -> Unsigned n
    complement# :: forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
    complement# = \(U Nat
    i) -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Nat
    complementN Nat
    i)
      where complementN :: Nat -> Nat
    complementN = Nat -> Nat -> Nat
    complementMod (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))

    shiftL#, shiftR#, rotateL#, rotateR# :: forall n .KnownNat n => Unsigned n -> Int -> Unsigned n
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE shiftL# #-}
    {-# ANN shiftL# hasBlackBox #-}
    shiftL# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    shiftL# = \(U Nat
    v) Int
    i ->
    #if MIN_VERSION_base(4,15,0)
      let i' :: Word
    i' = Int -> Word
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i in
      if | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0     -> String -> Unsigned n
    forall a. HasCallStack => String -> a
    error (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'shiftL' undefined for negative number: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    i
         | Word
    i' Word -> Word -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Word
    sz  -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U Nat
    0
         | Bool
    otherwise -> Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U ((Nat -> Word -> Nat
    naturalShiftL Nat
    v Word
    i') Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)
     where
      sz :: Word
    sz = Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
      m :: Nat
    m  = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Word
    sz
    #else
      if | i < 0     -> error $ "'shiftL' undefined for negative number: " ++ show i
         | i >= sz   -> U 0
         | otherwise -> U ((shiftL v i) `mod` m)
     where
      sz = fromInteger (natVal (Proxy @n))
      m  = 1 `shiftL` sz
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE shiftR# #-}
    {-# ANN shiftR# hasBlackBox #-}
    -- shiftR# doesn't need the KnownNat constraint
    -- But having the same type signature for all shift and rotate functions
    -- makes implementing the Evaluator easier.
    shiftR# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    shiftR# (U Nat
    v) Int
    i
      | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0     = String -> Unsigned n
    forall a. HasCallStack => String -> a
    error
                  (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'shiftR' undefined for negative number: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    i
      | Bool
    otherwise = Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat -> Int -> Nat
    forall a. Bits a => a -> Int -> a
    shiftR Nat
    v Int
    i)

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE rotateL# #-}
    {-# ANN rotateL# hasBlackBox #-}
    rotateL# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    rotateL# =
      \(U Nat
    n) Int
    b ->
        if Int
    b Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    0 then
    #if MIN_VERSION_base(4,15,0)
          let l :: Nat
    l   = Nat -> Word -> Nat
    naturalShiftL Nat
    n Word
    b'
              r :: Nat
    r   = Nat -> Word -> Nat
    naturalShiftR Nat
    n Word
    b''
              b' :: Word
    b'  = Int -> Word
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    b Word -> Word -> Word
    forall a. Integral a => a -> a -> a
    `mod` Word
    sz
    #else
          let l   = shiftL n b'
              r   = shiftR n b''
              b'  = b `mod` sz
    #endif
              b'' :: Word
    b'' = Word
    sz Word -> Word -> Word
    forall a. Num a => a -> a -> a
    - Word
    b'
          in  Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U ((Nat
    l Nat -> Nat -> Nat
    forall a. Bits a => a -> a -> a
    .|. Nat
    r) Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)
        else
          String -> Unsigned n
    forall a. HasCallStack => String -> a
    error (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'rotateL' undefined for negative number: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    b
      where
    #if MIN_VERSION_base(4,15,0)
        sz :: Word
    sz = Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
        m :: Nat
    m  = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Word
    sz
    #else
        sz = fromInteger (natVal (Proxy @n)) :: Int
        m  = 1 `shiftL` sz
    #endif

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE rotateR# #-}
    {-# ANN rotateR# hasBlackBox #-}
    rotateR# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
    rotateR# =
      \(U Nat
    n) Int
    b ->
        if Int
    b Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    0 then
    #if MIN_VERSION_base(4,15,0)
          let l :: Nat
    l   = Nat -> Word -> Nat
    naturalShiftR Nat
    n Word
    b'
              r :: Nat
    r   = Nat -> Word -> Nat
    naturalShiftL Nat
    n Word
    b''
              b' :: Word
    b'  = Int -> Word
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    b Word -> Word -> Word
    forall a. Integral a => a -> a -> a
    `mod` Word
    sz
    #else
          let l   = shiftR n b'
              r   = shiftL n b''
              b'  = b `mod` sz
    #endif
              b'' :: Word
    b'' = Word
    sz Word -> Word -> Word
    forall a. Num a => a -> a -> a
    - Word
    b'
          in  Nat -> Unsigned n
    forall (n :: Nat). Nat -> Unsigned n
    U ((Nat
    l Nat -> Nat -> Nat
    forall a. Bits a => a -> a -> a
    .|. Nat
    r) Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m)
        else
          String -> Unsigned n
    forall a. HasCallStack => String -> a
    error (String -> Unsigned n) -> String -> Unsigned n
    forall a b. (a -> b) -> a -> b
    $ String
    "'rotateR' undefined for negative number: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    b
      where
    #if MIN_VERSION_base(4,15,0)
        sz :: Word
    sz = Nat -> Word
    naturalToWord (Proxy n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @n))
        m :: Nat
    m  = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Word
    sz
    #else
        sz = fromInteger (natVal (Proxy @n)) :: Int
        m  = 1 `shiftL` sz
    #endif

    instance KnownNat n => FiniteBits (Unsigned n) where
      finiteBitSize :: Unsigned n -> Int
    finiteBitSize        = Unsigned n -> Int
    forall (n :: Nat). KnownNat n => Unsigned n -> Int
    size#
      countLeadingZeros :: Unsigned n -> Int
    countLeadingZeros  Unsigned n
    u = BitVector n -> Int
    forall b. FiniteBits b => b -> Int
    countLeadingZeros  (Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack# Unsigned n
    u)
      countTrailingZeros :: Unsigned n -> Int
    countTrailingZeros Unsigned n
    u = BitVector n -> Int
    forall b. FiniteBits b => b -> Int
    countTrailingZeros (Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack# Unsigned n
    u)

    instance Resize Unsigned where
      resize :: forall (a :: Nat) (b :: Nat).
    (KnownNat a, KnownNat b) =>
    Unsigned a -> Unsigned b
    resize     = Unsigned a -> Unsigned b
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize#
      zeroExtend :: forall (a :: Nat) (b :: Nat).
    (KnownNat a, KnownNat b) =>
    Unsigned a -> Unsigned (b + a)
    zeroExtend = Unsigned a -> Unsigned (b + a)
    forall (a :: Nat) (b :: Nat).
    (KnownNat a, KnownNat b) =>
    Unsigned a -> Unsigned (b + a)
    forall (f :: Nat -> Type) (a :: Nat) (b :: Nat).
    (Resize f, KnownNat a, KnownNat b) =>
    f a -> f (b + a)
    extend
      truncateB :: forall (a :: Nat) (b :: Nat).
    KnownNat a =>
    Unsigned (a + b) -> Unsigned a
    truncateB  = Unsigned (a + b) -> Unsigned a
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize#

    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE resize# #-}
    {-# ANN resize# hasBlackBox #-}
    resize# :: forall n m . KnownNat m => Unsigned n -> Unsigned m
    resize# :: forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# = \(U Nat
    i) -> if Nat
    i Nat -> Nat -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Nat
    m then Nat -> Unsigned m
    forall (n :: Nat). Nat -> Unsigned n
    U (Nat
    i Nat -> Nat -> Nat
    forall a. Integral a => a -> a -> a
    `mod` Nat
    m) else Nat -> Unsigned m
    forall (n :: Nat). Nat -> Unsigned n
    U Nat
    i
    #if MIN_VERSION_base(4,15,0)
      where m :: Nat
    m = Nat
    1 Nat -> Word -> Nat
    `naturalShiftL` Nat -> Word
    naturalToWord (Proxy m -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @m))
    #else
      where m = 1 `shiftL` fromInteger (natVal (Proxy @m))
    #endif

    instance Default (Unsigned n) where
      def :: Unsigned n
    def = Unsigned n
    forall (n :: Nat). Unsigned n
    minBound#

    instance KnownNat n => Lift (Unsigned n) where
      lift :: forall (m :: Type -> Type). Quote m => Unsigned n -> m Exp
    lift u :: Unsigned n
    u@(U Nat
    i) = m Exp -> m Type -> m Exp
    forall (m :: Type -> Type). Quote m => m Exp -> m Type -> m Exp
    sigE [| fromInteger# i |] (Nat -> m Type
    forall (m :: Type -> Type). Quote m => Nat -> m Type
    decUnsigned (Unsigned n -> Nat
    forall (n :: Nat) (proxy :: Nat -> Type).
    KnownNat n =>
    proxy n -> Nat
    natVal Unsigned n
    u))
      {-# NOINLINE lift #-}
    #if MIN_VERSION_template_haskell(2,16,0)
      liftTyped :: forall (m :: Type -> Type).
    Quote m =>
    Unsigned n -> Code m (Unsigned n)
    liftTyped = Unsigned n -> Code m (Unsigned n)
    forall a (m :: Type -> Type). (Lift a, Quote m) => a -> Code m a
    liftTypedFromUntyped
    #endif

    #if MIN_VERSION_template_haskell(2,17,0)
    decUnsigned :: Quote m => Natural -> m Type
    decUnsigned :: forall (m :: Type -> Type). Quote m => Nat -> m Type
    decUnsigned Nat
    n = m Type -> m Type -> m Type
    forall (m :: Type -> Type). Quote m => m Type -> m Type -> m Type
    appT (Name -> m Type
    forall (m :: Type -> Type). Quote m => Name -> m Type
    conT ''Unsigned) (m TyLit -> m Type
    forall (m :: Type -> Type). Quote m => m TyLit -> m Type
    litT (m TyLit -> m Type) -> m TyLit -> m Type
    forall a b. (a -> b) -> a -> b
    $ Integer -> m TyLit
    forall (m :: Type -> Type). Quote m => Integer -> m TyLit
    numTyLit (Nat -> Integer
    integerFromNatural Nat
    n))
    #else
    decUnsigned :: Integer -> TypeQ
    decUnsigned n = appT (conT ''Unsigned) (litT $ numTyLit n)
    #endif

    instance KnownNat n => SaturatingNum (Unsigned n) where
      satAdd :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
    satAdd SaturationMode
    SatWrap Unsigned n
    a Unsigned n
    b = Unsigned n
    a Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    +# Unsigned n
    b
      satAdd SaturationMode
    SatZero Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (Max n n + 1)
    r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus# Unsigned n
    a Unsigned n
    b
        in  case Unsigned (n + 1) -> Bit
    forall a. BitPack a => a -> Bit
    msb Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r of
              Bit
    0 -> Unsigned (n + 1) -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r
              Bit
    _ -> Unsigned n
    forall (n :: Nat). Unsigned n
    minBound#
      satAdd SaturationMode
    SatError Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (Max n n + 1)
    r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus# Unsigned n
    a Unsigned n
    b
        in  case Unsigned (n + 1) -> Bit
    forall a. BitPack a => a -> Bit
    msb Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r of
              Bit
    0 -> Unsigned (n + 1) -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r
              Bit
    _ -> String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX String
    "Unsigned.satAdd: overflow"
      satAdd SaturationMode
    _ Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (Max n n + 1)
    r  = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    plus# Unsigned n
    a Unsigned n
    b
        in  case Unsigned (n + 1) -> Bit
    forall a. BitPack a => a -> Bit
    msb Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r of
              Bit
    0 -> Unsigned (n + 1) -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r
              Bit
    _ -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n
    maxBound#

      satSub :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
    satSub SaturationMode
    SatWrap Unsigned n
    a Unsigned n
    b = Unsigned n
    a Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    -# Unsigned n
    b
      satSub SaturationMode
    SatError Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (Max n n + 1)
    r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
    forall (m :: Nat) (n :: Nat).
    (KnownNat m, KnownNat n) =>
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    minus# Unsigned n
    a Unsigned n
    b
        in  case Unsigned (n + 1) -> Bit
    forall a. BitPack a => a -> Bit
    msb Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r of
              Bit
    0 -> Unsigned (n + 1) -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r
              Bit
    _ -> String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX String
    "Unsigned.satSub: overflow"
      satSub SaturationMode
    _ Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (Max n n + 1)
    r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
    forall (m :: Nat) (n :: Nat).
    (KnownNat m, KnownNat n) =>
    Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
    minus# Unsigned n
    a Unsigned n
    b
        in  case Unsigned (n + 1) -> Bit
    forall a. BitPack a => a -> Bit
    msb Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r of
              Bit
    0 -> Unsigned (n + 1) -> Unsigned n
    forall (n :: Nat) (m :: Nat).
    KnownNat m =>
    Unsigned n -> Unsigned m
    resize# Unsigned (n + 1)
    Unsigned (Max n n + 1)
    r
              Bit
    _ -> Unsigned n
    forall (n :: Nat). Unsigned n
    minBound#

      satMul :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
    satMul SaturationMode
    SatWrap Unsigned n
    a Unsigned n
    b = Unsigned n
    a Unsigned n -> Unsigned n -> Unsigned n
    forall (n :: Nat).
    KnownNat n =>
    Unsigned n -> Unsigned n -> Unsigned n
    *# Unsigned n
    b
      satMul SaturationMode
    SatZero Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (n + n)
    r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    times# Unsigned n
    a Unsigned n
    b
            (BitVector n
    rL,BitVector n
    rR) = Unsigned (n + n) -> (BitVector n, BitVector n)
    forall a (m :: Nat) (n :: Nat).
    (BitPack a, BitSize a ~ (m + n), KnownNat n) =>
    a -> (BitVector m, BitVector n)
    split Unsigned (n + n)
    r
        in  case BitVector n
    rL of
              BitVector n
    0 -> BitVector n -> Unsigned n
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# BitVector n
    rR
              BitVector n
    _ -> Unsigned n
    forall (n :: Nat). Unsigned n
    minBound#
      satMul SaturationMode
    SatError Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (n + n)
    r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    times# Unsigned n
    a Unsigned n
    b
            (BitVector n
    rL,BitVector n
    rR) = Unsigned (n + n) -> (BitVector n, BitVector n)
    forall a (m :: Nat) (n :: Nat).
    (BitPack a, BitSize a ~ (m + n), KnownNat n) =>
    a -> (BitVector m, BitVector n)
    split Unsigned (n + n)
    r
        in  case BitVector n
    rL of
              BitVector n
    0 -> BitVector n -> Unsigned n
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# BitVector n
    rR
              BitVector n
    _ -> String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX String
    "Unsigned.satMul: overflow"
      satMul SaturationMode
    _ Unsigned n
    a Unsigned n
    b =
        let r :: Unsigned (n + n)
    r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
    forall (m :: Nat) (n :: Nat).
    Unsigned m -> Unsigned n -> Unsigned (m + n)
    times# Unsigned n
    a Unsigned n
    b
            (BitVector n
    rL,BitVector n
    rR) = Unsigned (n + n) -> (BitVector n, BitVector n)
    forall a (m :: Nat) (n :: Nat).
    (BitPack a, BitSize a ~ (m + n), KnownNat n) =>
    a -> (BitVector m, BitVector n)
    split Unsigned (n + n)
    r
        in  case BitVector n
    rL of
              BitVector n
    0 -> BitVector n -> Unsigned n
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# BitVector n
    rR
              BitVector n
    _ -> Unsigned n
    forall (n :: Nat). KnownNat n => Unsigned n
    maxBound#

      -- Implementations for satSucc and satPred are needed because 1 :: Unsigned 0
      -- overflows to 0, meaning without the first check SatError would return 0.

      satSucc :: SaturationMode -> Unsigned n -> Unsigned n
    satSucc SaturationMode
    SatError Unsigned n
    a
        | Unsigned n
    a Unsigned n -> Unsigned n -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unsigned n
    forall a. Bounded a => a
    maxBound = String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX String
    "Unsigned.satSucc: overflow"
      satSucc SaturationMode
    satMode Unsigned n
    a = SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
    forall a. SaturatingNum a => SaturationMode -> a -> a -> a
    satAdd SaturationMode
    satMode Unsigned n
    a Unsigned n
    1
      {-# INLINE satSucc #-}

      satPred :: SaturationMode -> Unsigned n -> Unsigned n
    satPred SaturationMode
    SatError Unsigned n
    a
        | Unsigned n
    a Unsigned n -> Unsigned n -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unsigned n
    forall a. Bounded a => a
    minBound = String -> Unsigned n
    forall a. HasCallStack => String -> a
    errorX String
    "Unsigned.satPred: overflow"
      satPred SaturationMode
    satMode Unsigned n
    a = SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
    forall a. SaturatingNum a => SaturationMode -> a -> a -> a
    satSub SaturationMode
    satMode Unsigned n
    a Unsigned n
    1
      {-# INLINE satPred #-}

    instance KnownNat n => Arbitrary (Unsigned n) where
      arbitrary :: Gen (Unsigned n)
    arbitrary = Gen (Unsigned n)
    forall a. (Bounded a, Integral a) => Gen a
    arbitraryBoundedIntegral
      shrink :: Unsigned n -> [Unsigned n]
    shrink    = Unsigned n -> [Unsigned n]
    forall (n :: Nat) (p :: Nat -> Type).
    (KnownNat n, Integral (p n)) =>
    p n -> [p n]
    BV.shrinkSizedUnsigned

    instance KnownNat n => CoArbitrary (Unsigned n) where
      coarbitrary :: forall b. Unsigned n -> Gen b -> Gen b
    coarbitrary = Unsigned n -> Gen b -> Gen b
    forall a b. Integral a => a -> Gen b -> Gen b
    coarbitraryIntegral

    type instance Index   (Unsigned n) = Int
    type instance IxValue (Unsigned n) = Bit
    instance KnownNat n => Ixed (Unsigned n) where
      ix :: Index (Unsigned n)
    -> Traversal' (Unsigned n) (IxValue (Unsigned n))
    ix Index (Unsigned n)
    i IxValue (Unsigned n) -> f (IxValue (Unsigned n))
    f Unsigned n
    s = BitVector n -> Unsigned n
    forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
    unpack# (BitVector n -> Unsigned n)
    -> (Bit -> BitVector n) -> Bit -> Unsigned n
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> BitVector n -> Int -> Bit -> BitVector n
    forall (n :: Nat).
    KnownNat n =>
    BitVector n -> Int -> Bit -> BitVector n
    BV.replaceBit# (Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack# Unsigned n
    s) Int
    Index (Unsigned n)
    i
                         (Bit -> Unsigned n) -> f Bit -> f (Unsigned n)
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> IxValue (Unsigned n) -> f (IxValue (Unsigned n))
    f (BitVector n -> Int -> Bit
    forall (n :: Nat). KnownNat n => BitVector n -> Int -> Bit
    BV.index# (Unsigned n -> BitVector n
    forall (n :: Nat). Unsigned n -> BitVector n
    pack# Unsigned n
    s) Int
    Index (Unsigned n)
    i)

    instance (KnownNat n) => Ix (Unsigned n) where
      range :: (Unsigned n, Unsigned n) -> [Unsigned n]
    range (Unsigned n
    a, Unsigned n
    b) = [Unsigned n
    a..Unsigned n
    b]
      index :: (Unsigned n, Unsigned n) -> Unsigned n -> Int
    index ab :: (Unsigned n, Unsigned n)
    ab@(Unsigned n
    a, Unsigned n
    b) Unsigned n
    x
        | (Unsigned n, Unsigned n) -> Unsigned n -> Bool
    forall a. Ix a => (a, a) -> a -> Bool
    inRange (Unsigned n, Unsigned n)
    ab Unsigned n
    x = Unsigned n -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Unsigned n -> Int) -> Unsigned n -> Int
    forall a b. (a -> b) -> a -> b
    $ Unsigned n
    x Unsigned n -> Unsigned n -> Unsigned n
    forall a. Num a => a -> a -> a
    - Unsigned n
    a
        | Bool
    otherwise = String -> Int
    forall a. HasCallStack => String -> a
    error (String -> Int) -> String -> Int
    forall a b. (a -> b) -> a -> b
    $ String -> Unsigned n -> Unsigned n -> Unsigned n -> String
    forall r. PrintfType r => String -> r
    printf String
    "Index (%d) out of range ((%d, %d))" Unsigned n
    x Unsigned n
    a Unsigned n
    b
      inRange :: (Unsigned n, Unsigned n) -> Unsigned n -> Bool
    inRange (Unsigned n
    a, Unsigned n
    b) Unsigned n
    x = Unsigned n
    a Unsigned n -> Unsigned n -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Unsigned n
    x Bool -> Bool -> Bool
    && Unsigned n
    x Unsigned n -> Unsigned n -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Unsigned n
    b

    unsignedToWord :: Unsigned WORD_SIZE_IN_BITS -> Word
    #if MIN_VERSION_base(4,15,0)
    unsignedToWord :: Unsigned 64 -> Word
    unsignedToWord (U (NS Word#
    u#)) = Word# -> Word
    W# Word#
    u#
    unsignedToWord (U (NB ByteArray#
    u#)) = ByteArray# -> Word
    bigNatToWord ByteArray#
    u#
    #else
    unsignedToWord (U (NatS# u#)) = W# u#
    unsignedToWord (U (NatJ# u#)) = W# (bigNatToWord u#)
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE unsignedToWord #-}
    {-# ANN unsignedToWord hasBlackBox #-}

    unsigned8toWord8 :: Unsigned 8 -> Word8
    #if MIN_VERSION_base(4,16,0)
    unsigned8toWord8 :: Unsigned 8 -> Word8
    unsigned8toWord8 (U (NS Word#
    u#)) = Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    u#)
    unsigned8toWord8 (U (NB ByteArray#
    u#)) = Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# (ByteArray# -> Word#
    bigNatToWord# ByteArray#
    u#))
    #elif MIN_VERSION_base(4,15,0)
    unsigned8toWord8 (U (NS u#)) = W8# (narrow8Word# u#)
    unsigned8toWord8 (U (NB u#)) = W8# (narrow8Word# (bigNatToWord# u#))
    #else
    unsigned8toWord8 (U (NatS# u#)) = W8# (narrow8Word# u#)
    unsigned8toWord8 (U (NatJ# u#)) = W8# (narrow8Word# (bigNatToWord u#))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE unsigned8toWord8 #-}
    {-# ANN unsigned8toWord8 hasBlackBox #-}

    unsigned16toWord16 :: Unsigned 16 -> Word16
    #if MIN_VERSION_base(4,16,0)
    unsigned16toWord16 :: Unsigned 16 -> Word16
    unsigned16toWord16 (U (NS Word#
    u#)) = Word16# -> Word16
    W16# (Word# -> Word16#
    wordToWord16# Word#
    u#)
    unsigned16toWord16 (U (NB ByteArray#
    u#)) = Word16# -> Word16
    W16# (Word# -> Word16#
    wordToWord16# (ByteArray# -> Word#
    bigNatToWord# ByteArray#
    u#))
    #elif MIN_VERSION_base(4,15,0)
    unsigned16toWord16 (U (NS u#)) = W16# (narrow16Word# u#)
    unsigned16toWord16 (U (NB u#)) = W16# (narrow16Word# (bigNatToWord# u#))
    #else
    unsigned16toWord16 (U (NatS# u#)) = W16# (narrow16Word# u#)
    unsigned16toWord16 (U (NatJ# u#)) = W16# (narrow16Word# (bigNatToWord u#))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE unsigned16toWord16 #-}
    {-# ANN unsigned16toWord16 hasBlackBox #-}

    unsigned32toWord32 :: Unsigned 32 -> Word32
    #if MIN_VERSION_base(4,16,0)
    unsigned32toWord32 :: Unsigned 32 -> Word32
    unsigned32toWord32 (U (NS Word#
    u#)) = Word32# -> Word32
    W32# (Word# -> Word32#
    wordToWord32# Word#
    u#)
    unsigned32toWord32 (U (NB ByteArray#
    u#)) = Word32# -> Word32
    W32# (Word# -> Word32#
    wordToWord32# (ByteArray# -> Word#
    bigNatToWord# ByteArray#
    u#))
    #elif MIN_VERSION_base(4,15,0)
    unsigned32toWord32 (U (NS u#)) = W32# (narrow32Word# u#)
    unsigned32toWord32 (U (NB u#)) = W32# (narrow32Word# (bigNatToWord# u#))
    #else
    unsigned32toWord32 (U (NatS# u#)) = W32# (narrow32Word# u#)
    unsigned32toWord32 (U (NatJ# u#)) = W32# (narrow32Word# (bigNatToWord u#))
    #endif
    -- See: https://github.com/clash-lang/clash-compiler/pull/2511
    {-# CLASH_OPAQUE unsigned32toWord32 #-}
    {-# ANN unsigned32toWord32 hasBlackBox #-}

    {-# RULES
    "bitCoerce/Unsigned WORD_SIZE_IN_BITS -> Word" bitCoerce = unsignedToWord
    "bitCoerce/Unsigned 8 -> Word8" bitCoerce = unsigned8toWord8
    "bitCoerce/Unsigned 16 -> Word16" bitCoerce = unsigned16toWord16
    "bitCoerce/Unsigned 32 -> Word32" bitCoerce = unsigned32toWord32
     #-}