packages feed

clash-prelude 0.99.3 → 1.0.0

raw patch · 95 files changed

+15812/−6736 lines, 95 filesdep +binarydep +bytestringdep +containersdep −data-defaultdep ~QuickCheckdep ~basedep ~constraintsnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: binary, bytestring, containers, data-default-class, hashable, hint, tasty, tasty-hunit, text, th-lift, th-orphans, time, type-errors

Dependencies removed: data-default

Dependency ranges changed: QuickCheck, base, constraints, deepseq, doctest, ghc-prim, ghc-typelits-extra, ghc-typelits-knownnat, ghc-typelits-natnormalise, lens, template-haskell, transformers

API changes (from Hackage documentation)

- Clash.Class.BitPack: instance (Clash.Class.BitPack.BitPack a, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a)) => Clash.Class.BitPack.BitPack (GHC.Base.Maybe a)
- Clash.Class.BitPack: instance (GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize b), Clash.Class.BitPack.BitPack a, Clash.Class.BitPack.BitPack b) => Clash.Class.BitPack.BitPack (a, b)
- Clash.Class.BitPack: instance (GHC.TypeNats.KnownNat (Clash.Class.BitPack.GBitSize g), Clash.Class.BitPack.GBitPack f, Clash.Class.BitPack.GBitPack g) => Clash.Class.BitPack.GBitPack (f GHC.Generics.:*: g)
- Clash.Class.BitPack: instance Clash.Class.BitPack.BitPack (Clash.Sized.Internal.BitVector.BitVector n)
- Clash.Class.Num: boundedMin :: SaturatingNum a => a -> a -> a
- Clash.Class.Num: boundedMult :: SaturatingNum a => a -> a -> a
- Clash.Class.Num: boundedPlus :: SaturatingNum a => a -> a -> a
- Clash.Class.Num: minus :: ExtendingNum a b => a -> b -> AResult a b
- Clash.Class.Num: plus :: ExtendingNum a b => a -> b -> AResult a b
- Clash.Class.Num: satMin :: SaturatingNum a => SaturationMode -> a -> a -> a
- Clash.Class.Num: satMult :: SaturatingNum a => SaturationMode -> a -> a -> a
- Clash.Class.Num: satPlus :: SaturatingNum a => SaturationMode -> a -> a -> a
- Clash.Class.Num: times :: ExtendingNum a b => a -> b -> MResult a b
- Clash.Explicit.Prelude: ($!) :: () => a -> b -> a -> b
- Clash.Explicit.Prelude: ($) :: () => a -> b -> a -> b
- Clash.Explicit.Prelude: (&&) :: Bool -> Bool -> Bool
- Clash.Explicit.Prelude: (*) :: Num a => a -> a -> a
- Clash.Explicit.Prelude: (**) :: Floating a => a -> a -> a
- Clash.Explicit.Prelude: (*>) :: Applicative f => f a -> f b -> f b
- Clash.Explicit.Prelude: (+) :: Num a => a -> a -> a
- Clash.Explicit.Prelude: (-) :: Num a => a -> a -> a
- Clash.Explicit.Prelude: (.) :: () => b -> c -> a -> b -> a -> c
- Clash.Explicit.Prelude: (/) :: Fractional a => a -> a -> a
- Clash.Explicit.Prelude: (/=) :: Eq a => a -> a -> Bool
- Clash.Explicit.Prelude: (<$) :: Functor f => a -> f b -> f a
- Clash.Explicit.Prelude: (<$>) :: Functor f => a -> b -> f a -> f b
- Clash.Explicit.Prelude: (<) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude: (<*) :: Applicative f => f a -> f b -> f a
- Clash.Explicit.Prelude: (<*>) :: Applicative f => f a -> b -> f a -> f b
- Clash.Explicit.Prelude: (<=) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude: (<>) :: Semigroup a => a -> a -> a
- Clash.Explicit.Prelude: (=<<) :: Monad m => a -> m b -> m a -> m b
- Clash.Explicit.Prelude: (==) :: Eq a => a -> a -> Bool
- Clash.Explicit.Prelude: (>) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude: (>=) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude: (>>) :: Monad m => m a -> m b -> m b
- Clash.Explicit.Prelude: (>>=) :: Monad m => m a -> a -> m b -> m b
- Clash.Explicit.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
- Clash.Explicit.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
- Clash.Explicit.Prelude: (||) :: Bool -> Bool -> Bool
- Clash.Explicit.Prelude: EQ :: Ordering
- Clash.Explicit.Prelude: False :: Bool
- Clash.Explicit.Prelude: GT :: Ordering
- Clash.Explicit.Prelude: Just :: a -> Maybe a
- Clash.Explicit.Prelude: LT :: Ordering
- Clash.Explicit.Prelude: Left :: a -> Either a b
- Clash.Explicit.Prelude: Nothing :: Maybe a
- Clash.Explicit.Prelude: Right :: b -> Either a b
- Clash.Explicit.Prelude: True :: Bool
- Clash.Explicit.Prelude: abs :: Num a => a -> a
- Clash.Explicit.Prelude: acos :: Floating a => a -> a
- Clash.Explicit.Prelude: acosh :: Floating a => a -> a
- Clash.Explicit.Prelude: all :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Explicit.Prelude: and :: Foldable t => t Bool -> Bool
- Clash.Explicit.Prelude: any :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Explicit.Prelude: appendFile :: FilePath -> String -> IO ()
- Clash.Explicit.Prelude: asTypeOf :: () => a -> a -> a
- Clash.Explicit.Prelude: asin :: Floating a => a -> a
- Clash.Explicit.Prelude: asinh :: Floating a => a -> a
- Clash.Explicit.Prelude: atan :: Floating a => a -> a
- Clash.Explicit.Prelude: atan2 :: RealFloat a => a -> a -> a
- Clash.Explicit.Prelude: atanh :: Floating a => a -> a
- Clash.Explicit.Prelude: break :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Explicit.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude: class Functor f => Applicative (f :: * -> *)
- Clash.Explicit.Prelude: class Bounded a
- Clash.Explicit.Prelude: class Enum a
- Clash.Explicit.Prelude: class Eq a
- Clash.Explicit.Prelude: class Fractional a => Floating a
- Clash.Explicit.Prelude: class Foldable (t :: * -> *)
- Clash.Explicit.Prelude: class Num a => Fractional a
- Clash.Explicit.Prelude: class Functor (f :: * -> *)
- Clash.Explicit.Prelude: class (Real a, Enum a) => Integral a
- Clash.Explicit.Prelude: class Applicative m => Monad (m :: * -> *)
- Clash.Explicit.Prelude: class Semigroup a => Monoid a
- Clash.Explicit.Prelude: class Num a
- Clash.Explicit.Prelude: class Eq a => Ord a
- Clash.Explicit.Prelude: class Read a
- Clash.Explicit.Prelude: class (Num a, Ord a) => Real a
- Clash.Explicit.Prelude: class (RealFrac a, Floating a) => RealFloat a
- Clash.Explicit.Prelude: class (Real a, Fractional a) => RealFrac a
- Clash.Explicit.Prelude: class Semigroup a
- Clash.Explicit.Prelude: class Show a
- Clash.Explicit.Prelude: class (Functor t, Foldable t) => Traversable (t :: * -> *)
- Clash.Explicit.Prelude: compare :: Ord a => a -> a -> Ordering
- Clash.Explicit.Prelude: concatMap :: Foldable t => a -> [b] -> t a -> [b]
- Clash.Explicit.Prelude: const :: () => a -> b -> a
- Clash.Explicit.Prelude: cos :: Floating a => a -> a
- Clash.Explicit.Prelude: cosh :: Floating a => a -> a
- Clash.Explicit.Prelude: curry :: () => (a, b) -> c -> a -> b -> c
- Clash.Explicit.Prelude: cycle :: () => [a] -> [a]
- Clash.Explicit.Prelude: data Bool
- Clash.Explicit.Prelude: data Char
- Clash.Explicit.Prelude: data Double
- Clash.Explicit.Prelude: data Either a b
- Clash.Explicit.Prelude: data Float
- Clash.Explicit.Prelude: data IO a
- Clash.Explicit.Prelude: data Int
- Clash.Explicit.Prelude: data Integer
- Clash.Explicit.Prelude: data Maybe a
- Clash.Explicit.Prelude: data Ordering
- Clash.Explicit.Prelude: data Word
- Clash.Explicit.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
- Clash.Explicit.Prelude: div :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: divMod :: Integral a => a -> a -> (a, a)
- Clash.Explicit.Prelude: dropWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude: either :: () => a -> c -> b -> c -> Either a b -> c
- Clash.Explicit.Prelude: elem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Explicit.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
- Clash.Explicit.Prelude: enumFrom :: Enum a => a -> [a]
- Clash.Explicit.Prelude: enumFromThen :: Enum a => a -> a -> [a]
- Clash.Explicit.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- Clash.Explicit.Prelude: enumFromTo :: Enum a => a -> a -> [a]
- Clash.Explicit.Prelude: error :: HasCallStack => [Char] -> a
- Clash.Explicit.Prelude: errorWithoutStackTrace :: () => [Char] -> a
- Clash.Explicit.Prelude: even :: Integral a => a -> Bool
- Clash.Explicit.Prelude: exp :: Floating a => a -> a
- Clash.Explicit.Prelude: exponent :: RealFloat a => a -> Int
- Clash.Explicit.Prelude: fail :: Monad m => String -> m a
- Clash.Explicit.Prelude: filter :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude: flip :: () => a -> b -> c -> b -> a -> c
- Clash.Explicit.Prelude: floatDigits :: RealFloat a => a -> Int
- Clash.Explicit.Prelude: floatRadix :: RealFloat a => a -> Integer
- Clash.Explicit.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
- Clash.Explicit.Prelude: floor :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude: fmap :: Functor f => a -> b -> f a -> f b
- Clash.Explicit.Prelude: foldMap :: (Foldable t, Monoid m) => a -> m -> t a -> m
- Clash.Explicit.Prelude: fromEnum :: Enum a => a -> Int
- Clash.Explicit.Prelude: fromInteger :: Num a => Integer -> a
- Clash.Explicit.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
- Clash.Explicit.Prelude: fromRational :: Fractional a => Rational -> a
- Clash.Explicit.Prelude: fst :: () => (a, b) -> a
- Clash.Explicit.Prelude: gcd :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: getChar :: IO Char
- Clash.Explicit.Prelude: getContents :: IO String
- Clash.Explicit.Prelude: getLine :: IO String
- Clash.Explicit.Prelude: id :: () => a -> a
- Clash.Explicit.Prelude: infix 4 `notElem`
- Clash.Explicit.Prelude: infixl 4 <$>
- Clash.Explicit.Prelude: infixr 0 $!
- Clash.Explicit.Prelude: infixr 1 =<<
- Clash.Explicit.Prelude: infixr 2 ||
- Clash.Explicit.Prelude: infixr 3 &&
- Clash.Explicit.Prelude: infixr 8 ^
- Clash.Explicit.Prelude: infixr 9 .
- Clash.Explicit.Prelude: interact :: String -> String -> IO ()
- Clash.Explicit.Prelude: ioError :: () => IOError -> IO a
- Clash.Explicit.Prelude: isDenormalized :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude: isIEEE :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude: isInfinite :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude: isNaN :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude: isNegativeZero :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude: lcm :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: lex :: ReadS String
- Clash.Explicit.Prelude: lines :: String -> [String]
- Clash.Explicit.Prelude: log :: Floating a => a -> a
- Clash.Explicit.Prelude: logBase :: Floating a => a -> a -> a
- Clash.Explicit.Prelude: lookup :: Eq a => a -> [(a, b)] -> Maybe b
- Clash.Explicit.Prelude: mapM :: (Traversable t, Monad m) => a -> m b -> t a -> m t b
- Clash.Explicit.Prelude: mapM_ :: (Foldable t, Monad m) => a -> m b -> t a -> m ()
- Clash.Explicit.Prelude: mappend :: Monoid a => a -> a -> a
- Clash.Explicit.Prelude: max :: Ord a => a -> a -> a
- Clash.Explicit.Prelude: maxBound :: Bounded a => a
- Clash.Explicit.Prelude: maximum :: (Foldable t, Ord a) => t a -> a
- Clash.Explicit.Prelude: maybe :: () => b -> a -> b -> Maybe a -> b
- Clash.Explicit.Prelude: mconcat :: Monoid a => [a] -> a
- Clash.Explicit.Prelude: mempty :: Monoid a => a
- Clash.Explicit.Prelude: min :: Ord a => a -> a -> a
- Clash.Explicit.Prelude: minBound :: Bounded a => a
- Clash.Explicit.Prelude: minimum :: (Foldable t, Ord a) => t a -> a
- Clash.Explicit.Prelude: mod :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: negate :: Num a => a -> a
- Clash.Explicit.Prelude: not :: Bool -> Bool
- Clash.Explicit.Prelude: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Explicit.Prelude: null :: Foldable t => t a -> Bool
- Clash.Explicit.Prelude: odd :: Integral a => a -> Bool
- Clash.Explicit.Prelude: or :: Foldable t => t Bool -> Bool
- Clash.Explicit.Prelude: otherwise :: Bool
- Clash.Explicit.Prelude: outputVerifier :: forall l domain gated synchronous a. (KnownNat l, Eq a, ShowX a) => Clock domain gated -> Reset domain synchronous -> Vec l a -> Signal domain a -> Signal domain Bool
- Clash.Explicit.Prelude: pi :: Floating a => a
- Clash.Explicit.Prelude: pred :: Enum a => a -> a
- Clash.Explicit.Prelude: print :: Show a => a -> IO ()
- Clash.Explicit.Prelude: product :: (Foldable t, Num a) => t a -> a
- Clash.Explicit.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
- Clash.Explicit.Prelude: pure :: Applicative f => a -> f a
- Clash.Explicit.Prelude: putChar :: Char -> IO ()
- Clash.Explicit.Prelude: putStr :: String -> IO ()
- Clash.Explicit.Prelude: putStrLn :: String -> IO ()
- Clash.Explicit.Prelude: quot :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: quotRem :: Integral a => a -> a -> (a, a)
- Clash.Explicit.Prelude: read :: Read a => String -> a
- Clash.Explicit.Prelude: readFile :: FilePath -> IO String
- Clash.Explicit.Prelude: readIO :: Read a => String -> IO a
- Clash.Explicit.Prelude: readList :: Read a => ReadS [a]
- Clash.Explicit.Prelude: readLn :: Read a => IO a
- Clash.Explicit.Prelude: readParen :: () => Bool -> ReadS a -> ReadS a
- Clash.Explicit.Prelude: reads :: Read a => ReadS a
- Clash.Explicit.Prelude: readsPrec :: Read a => Int -> ReadS a
- Clash.Explicit.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
- Clash.Explicit.Prelude: recip :: Fractional a => a -> a
- Clash.Explicit.Prelude: rem :: Integral a => a -> a -> a
- Clash.Explicit.Prelude: return :: Monad m => a -> m a
- Clash.Explicit.Prelude: round :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude: scaleFloat :: RealFloat a => Int -> a -> a
- Clash.Explicit.Prelude: scanl1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Explicit.Prelude: scanr1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Explicit.Prelude: seq :: () => a -> b -> b
- Clash.Explicit.Prelude: sequence :: (Traversable t, Monad m) => t m a -> m t a
- Clash.Explicit.Prelude: sequenceA :: (Traversable t, Applicative f) => t f a -> f t a
- Clash.Explicit.Prelude: sequence_ :: (Foldable t, Monad m) => t m a -> m ()
- Clash.Explicit.Prelude: show :: Show a => a -> String
- Clash.Explicit.Prelude: showChar :: Char -> ShowS
- Clash.Explicit.Prelude: showList :: Show a => [a] -> ShowS
- Clash.Explicit.Prelude: showParen :: Bool -> ShowS -> ShowS
- Clash.Explicit.Prelude: showString :: String -> ShowS
- Clash.Explicit.Prelude: shows :: Show a => a -> ShowS
- Clash.Explicit.Prelude: showsPrec :: Show a => Int -> a -> ShowS
- Clash.Explicit.Prelude: significand :: RealFloat a => a -> a
- Clash.Explicit.Prelude: signum :: Num a => a -> a
- Clash.Explicit.Prelude: sin :: Floating a => a -> a
- Clash.Explicit.Prelude: sinh :: Floating a => a -> a
- Clash.Explicit.Prelude: snd :: () => (a, b) -> b
- Clash.Explicit.Prelude: span :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Explicit.Prelude: sqrt :: Floating a => a -> a
- Clash.Explicit.Prelude: subtract :: Num a => a -> a -> a
- Clash.Explicit.Prelude: succ :: Enum a => a -> a
- Clash.Explicit.Prelude: sum :: (Foldable t, Num a) => t a -> a
- Clash.Explicit.Prelude: takeWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude: tan :: Floating a => a -> a
- Clash.Explicit.Prelude: tanh :: Floating a => a -> a
- Clash.Explicit.Prelude: toEnum :: Enum a => Int -> a
- Clash.Explicit.Prelude: toInteger :: Integral a => a -> Integer
- Clash.Explicit.Prelude: toRational :: Real a => a -> Rational
- Clash.Explicit.Prelude: traverse :: (Traversable t, Applicative f) => a -> f b -> t a -> f t b
- Clash.Explicit.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude: type FilePath = String
- Clash.Explicit.Prelude: type IOError = IOException
- Clash.Explicit.Prelude: type Rational = Ratio Integer
- Clash.Explicit.Prelude: type ReadS a = String -> [(a, String)]
- Clash.Explicit.Prelude: type ShowS = String -> String
- Clash.Explicit.Prelude: type String = [Char]
- Clash.Explicit.Prelude: uncurry :: () => a -> b -> c -> (a, b) -> c
- Clash.Explicit.Prelude: unlines :: [String] -> String
- Clash.Explicit.Prelude: until :: () => a -> Bool -> a -> a -> a -> a
- Clash.Explicit.Prelude: unwords :: [String] -> String
- Clash.Explicit.Prelude: userError :: String -> IOError
- Clash.Explicit.Prelude: words :: String -> [String]
- Clash.Explicit.Prelude: writeFile :: FilePath -> String -> IO ()
- Clash.Explicit.Prelude.Safe: ($!) :: () => a -> b -> a -> b
- Clash.Explicit.Prelude.Safe: ($) :: () => a -> b -> a -> b
- Clash.Explicit.Prelude.Safe: (&&) :: Bool -> Bool -> Bool
- Clash.Explicit.Prelude.Safe: (*) :: Num a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (**) :: Floating a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (*>) :: Applicative f => f a -> f b -> f b
- Clash.Explicit.Prelude.Safe: (+) :: Num a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (-) :: Num a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (.) :: () => b -> c -> a -> b -> a -> c
- Clash.Explicit.Prelude.Safe: (/) :: Fractional a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (/=) :: Eq a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (<$) :: Functor f => a -> f b -> f a
- Clash.Explicit.Prelude.Safe: (<$>) :: Functor f => a -> b -> f a -> f b
- Clash.Explicit.Prelude.Safe: (<) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (<*) :: Applicative f => f a -> f b -> f a
- Clash.Explicit.Prelude.Safe: (<*>) :: Applicative f => f a -> b -> f a -> f b
- Clash.Explicit.Prelude.Safe: (<=) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (<>) :: Semigroup a => a -> a -> a
- Clash.Explicit.Prelude.Safe: (=<<) :: Monad m => a -> m b -> m a -> m b
- Clash.Explicit.Prelude.Safe: (==) :: Eq a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (>) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (>=) :: Ord a => a -> a -> Bool
- Clash.Explicit.Prelude.Safe: (>>) :: Monad m => m a -> m b -> m b
- Clash.Explicit.Prelude.Safe: (>>=) :: Monad m => m a -> a -> m b -> m b
- Clash.Explicit.Prelude.Safe: (^) :: (Num a, Integral b) => a -> b -> a
- Clash.Explicit.Prelude.Safe: (^^) :: (Fractional a, Integral b) => a -> b -> a
- Clash.Explicit.Prelude.Safe: (||) :: Bool -> Bool -> Bool
- Clash.Explicit.Prelude.Safe: EQ :: Ordering
- Clash.Explicit.Prelude.Safe: False :: Bool
- Clash.Explicit.Prelude.Safe: GT :: Ordering
- Clash.Explicit.Prelude.Safe: Just :: a -> Maybe a
- Clash.Explicit.Prelude.Safe: LT :: Ordering
- Clash.Explicit.Prelude.Safe: Left :: a -> Either a b
- Clash.Explicit.Prelude.Safe: Nothing :: Maybe a
- Clash.Explicit.Prelude.Safe: Right :: b -> Either a b
- Clash.Explicit.Prelude.Safe: True :: Bool
- Clash.Explicit.Prelude.Safe: abs :: Num a => a -> a
- Clash.Explicit.Prelude.Safe: acos :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: acosh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: all :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Explicit.Prelude.Safe: and :: Foldable t => t Bool -> Bool
- Clash.Explicit.Prelude.Safe: any :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Explicit.Prelude.Safe: appendFile :: FilePath -> String -> IO ()
- Clash.Explicit.Prelude.Safe: asTypeOf :: () => a -> a -> a
- Clash.Explicit.Prelude.Safe: asin :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: asinh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: atan :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: atan2 :: RealFloat a => a -> a -> a
- Clash.Explicit.Prelude.Safe: atanh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: break :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Explicit.Prelude.Safe: ceiling :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude.Safe: class Functor f => Applicative (f :: * -> *)
- Clash.Explicit.Prelude.Safe: class Bounded a
- Clash.Explicit.Prelude.Safe: class Enum a
- Clash.Explicit.Prelude.Safe: class Eq a
- Clash.Explicit.Prelude.Safe: class Fractional a => Floating a
- Clash.Explicit.Prelude.Safe: class Foldable (t :: * -> *)
- Clash.Explicit.Prelude.Safe: class Num a => Fractional a
- Clash.Explicit.Prelude.Safe: class Functor (f :: * -> *)
- Clash.Explicit.Prelude.Safe: class (Real a, Enum a) => Integral a
- Clash.Explicit.Prelude.Safe: class Applicative m => Monad (m :: * -> *)
- Clash.Explicit.Prelude.Safe: class Semigroup a => Monoid a
- Clash.Explicit.Prelude.Safe: class Num a
- Clash.Explicit.Prelude.Safe: class Eq a => Ord a
- Clash.Explicit.Prelude.Safe: class Read a
- Clash.Explicit.Prelude.Safe: class (Num a, Ord a) => Real a
- Clash.Explicit.Prelude.Safe: class (RealFrac a, Floating a) => RealFloat a
- Clash.Explicit.Prelude.Safe: class (Real a, Fractional a) => RealFrac a
- Clash.Explicit.Prelude.Safe: class Semigroup a
- Clash.Explicit.Prelude.Safe: class Show a
- Clash.Explicit.Prelude.Safe: class (Functor t, Foldable t) => Traversable (t :: * -> *)
- Clash.Explicit.Prelude.Safe: compare :: Ord a => a -> a -> Ordering
- Clash.Explicit.Prelude.Safe: concatMap :: Foldable t => a -> [b] -> t a -> [b]
- Clash.Explicit.Prelude.Safe: const :: () => a -> b -> a
- Clash.Explicit.Prelude.Safe: cos :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: cosh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: curry :: () => (a, b) -> c -> a -> b -> c
- Clash.Explicit.Prelude.Safe: cycle :: () => [a] -> [a]
- Clash.Explicit.Prelude.Safe: data Bool
- Clash.Explicit.Prelude.Safe: data Char
- Clash.Explicit.Prelude.Safe: data Double
- Clash.Explicit.Prelude.Safe: data Either a b
- Clash.Explicit.Prelude.Safe: data Float
- Clash.Explicit.Prelude.Safe: data IO a
- Clash.Explicit.Prelude.Safe: data Int
- Clash.Explicit.Prelude.Safe: data Integer
- Clash.Explicit.Prelude.Safe: data Maybe a
- Clash.Explicit.Prelude.Safe: data Ordering
- Clash.Explicit.Prelude.Safe: data Word
- Clash.Explicit.Prelude.Safe: decodeFloat :: RealFloat a => a -> (Integer, Int)
- Clash.Explicit.Prelude.Safe: div :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: divMod :: Integral a => a -> a -> (a, a)
- Clash.Explicit.Prelude.Safe: dropWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude.Safe: either :: () => a -> c -> b -> c -> Either a b -> c
- Clash.Explicit.Prelude.Safe: elem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Explicit.Prelude.Safe: encodeFloat :: RealFloat a => Integer -> Int -> a
- Clash.Explicit.Prelude.Safe: enumFrom :: Enum a => a -> [a]
- Clash.Explicit.Prelude.Safe: enumFromThen :: Enum a => a -> a -> [a]
- Clash.Explicit.Prelude.Safe: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- Clash.Explicit.Prelude.Safe: enumFromTo :: Enum a => a -> a -> [a]
- Clash.Explicit.Prelude.Safe: error :: HasCallStack => [Char] -> a
- Clash.Explicit.Prelude.Safe: errorWithoutStackTrace :: () => [Char] -> a
- Clash.Explicit.Prelude.Safe: even :: Integral a => a -> Bool
- Clash.Explicit.Prelude.Safe: exp :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: exponent :: RealFloat a => a -> Int
- Clash.Explicit.Prelude.Safe: fail :: Monad m => String -> m a
- Clash.Explicit.Prelude.Safe: filter :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude.Safe: flip :: () => a -> b -> c -> b -> a -> c
- Clash.Explicit.Prelude.Safe: floatDigits :: RealFloat a => a -> Int
- Clash.Explicit.Prelude.Safe: floatRadix :: RealFloat a => a -> Integer
- Clash.Explicit.Prelude.Safe: floatRange :: RealFloat a => a -> (Int, Int)
- Clash.Explicit.Prelude.Safe: floor :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude.Safe: fmap :: Functor f => a -> b -> f a -> f b
- Clash.Explicit.Prelude.Safe: foldMap :: (Foldable t, Monoid m) => a -> m -> t a -> m
- Clash.Explicit.Prelude.Safe: fromEnum :: Enum a => a -> Int
- Clash.Explicit.Prelude.Safe: fromInteger :: Num a => Integer -> a
- Clash.Explicit.Prelude.Safe: fromIntegral :: (Integral a, Num b) => a -> b
- Clash.Explicit.Prelude.Safe: fromRational :: Fractional a => Rational -> a
- Clash.Explicit.Prelude.Safe: fst :: () => (a, b) -> a
- Clash.Explicit.Prelude.Safe: gcd :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: getChar :: IO Char
- Clash.Explicit.Prelude.Safe: getContents :: IO String
- Clash.Explicit.Prelude.Safe: getLine :: IO String
- Clash.Explicit.Prelude.Safe: id :: () => a -> a
- Clash.Explicit.Prelude.Safe: infix 4 `notElem`
- Clash.Explicit.Prelude.Safe: infixl 4 <$>
- Clash.Explicit.Prelude.Safe: infixr 0 $!
- Clash.Explicit.Prelude.Safe: infixr 1 =<<
- Clash.Explicit.Prelude.Safe: infixr 2 ||
- Clash.Explicit.Prelude.Safe: infixr 3 &&
- Clash.Explicit.Prelude.Safe: infixr 8 ^
- Clash.Explicit.Prelude.Safe: infixr 9 .
- Clash.Explicit.Prelude.Safe: interact :: String -> String -> IO ()
- Clash.Explicit.Prelude.Safe: ioError :: () => IOError -> IO a
- Clash.Explicit.Prelude.Safe: isDenormalized :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude.Safe: isIEEE :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude.Safe: isInfinite :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude.Safe: isNaN :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude.Safe: isNegativeZero :: RealFloat a => a -> Bool
- Clash.Explicit.Prelude.Safe: lcm :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: lex :: ReadS String
- Clash.Explicit.Prelude.Safe: lines :: String -> [String]
- Clash.Explicit.Prelude.Safe: log :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: logBase :: Floating a => a -> a -> a
- Clash.Explicit.Prelude.Safe: lookup :: Eq a => a -> [(a, b)] -> Maybe b
- Clash.Explicit.Prelude.Safe: mapM :: (Traversable t, Monad m) => a -> m b -> t a -> m t b
- Clash.Explicit.Prelude.Safe: mapM_ :: (Foldable t, Monad m) => a -> m b -> t a -> m ()
- Clash.Explicit.Prelude.Safe: mappend :: Monoid a => a -> a -> a
- Clash.Explicit.Prelude.Safe: max :: Ord a => a -> a -> a
- Clash.Explicit.Prelude.Safe: maxBound :: Bounded a => a
- Clash.Explicit.Prelude.Safe: maximum :: (Foldable t, Ord a) => t a -> a
- Clash.Explicit.Prelude.Safe: maybe :: () => b -> a -> b -> Maybe a -> b
- Clash.Explicit.Prelude.Safe: mconcat :: Monoid a => [a] -> a
- Clash.Explicit.Prelude.Safe: mempty :: Monoid a => a
- Clash.Explicit.Prelude.Safe: min :: Ord a => a -> a -> a
- Clash.Explicit.Prelude.Safe: minBound :: Bounded a => a
- Clash.Explicit.Prelude.Safe: minimum :: (Foldable t, Ord a) => t a -> a
- Clash.Explicit.Prelude.Safe: mod :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: negate :: Num a => a -> a
- Clash.Explicit.Prelude.Safe: not :: Bool -> Bool
- Clash.Explicit.Prelude.Safe: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Explicit.Prelude.Safe: null :: Foldable t => t a -> Bool
- Clash.Explicit.Prelude.Safe: odd :: Integral a => a -> Bool
- Clash.Explicit.Prelude.Safe: or :: Foldable t => t Bool -> Bool
- Clash.Explicit.Prelude.Safe: otherwise :: Bool
- Clash.Explicit.Prelude.Safe: pi :: Floating a => a
- Clash.Explicit.Prelude.Safe: pred :: Enum a => a -> a
- Clash.Explicit.Prelude.Safe: print :: Show a => a -> IO ()
- Clash.Explicit.Prelude.Safe: product :: (Foldable t, Num a) => t a -> a
- Clash.Explicit.Prelude.Safe: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
- Clash.Explicit.Prelude.Safe: pure :: Applicative f => a -> f a
- Clash.Explicit.Prelude.Safe: putChar :: Char -> IO ()
- Clash.Explicit.Prelude.Safe: putStr :: String -> IO ()
- Clash.Explicit.Prelude.Safe: putStrLn :: String -> IO ()
- Clash.Explicit.Prelude.Safe: quot :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: quotRem :: Integral a => a -> a -> (a, a)
- Clash.Explicit.Prelude.Safe: read :: Read a => String -> a
- Clash.Explicit.Prelude.Safe: readFile :: FilePath -> IO String
- Clash.Explicit.Prelude.Safe: readIO :: Read a => String -> IO a
- Clash.Explicit.Prelude.Safe: readList :: Read a => ReadS [a]
- Clash.Explicit.Prelude.Safe: readLn :: Read a => IO a
- Clash.Explicit.Prelude.Safe: readParen :: () => Bool -> ReadS a -> ReadS a
- Clash.Explicit.Prelude.Safe: reads :: Read a => ReadS a
- Clash.Explicit.Prelude.Safe: readsPrec :: Read a => Int -> ReadS a
- Clash.Explicit.Prelude.Safe: realToFrac :: (Real a, Fractional b) => a -> b
- Clash.Explicit.Prelude.Safe: recip :: Fractional a => a -> a
- Clash.Explicit.Prelude.Safe: rem :: Integral a => a -> a -> a
- Clash.Explicit.Prelude.Safe: return :: Monad m => a -> m a
- Clash.Explicit.Prelude.Safe: round :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude.Safe: scaleFloat :: RealFloat a => Int -> a -> a
- Clash.Explicit.Prelude.Safe: scanl1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Explicit.Prelude.Safe: scanr1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Explicit.Prelude.Safe: seq :: () => a -> b -> b
- Clash.Explicit.Prelude.Safe: sequence :: (Traversable t, Monad m) => t m a -> m t a
- Clash.Explicit.Prelude.Safe: sequenceA :: (Traversable t, Applicative f) => t f a -> f t a
- Clash.Explicit.Prelude.Safe: sequence_ :: (Foldable t, Monad m) => t m a -> m ()
- Clash.Explicit.Prelude.Safe: show :: Show a => a -> String
- Clash.Explicit.Prelude.Safe: showChar :: Char -> ShowS
- Clash.Explicit.Prelude.Safe: showList :: Show a => [a] -> ShowS
- Clash.Explicit.Prelude.Safe: showParen :: Bool -> ShowS -> ShowS
- Clash.Explicit.Prelude.Safe: showString :: String -> ShowS
- Clash.Explicit.Prelude.Safe: shows :: Show a => a -> ShowS
- Clash.Explicit.Prelude.Safe: showsPrec :: Show a => Int -> a -> ShowS
- Clash.Explicit.Prelude.Safe: significand :: RealFloat a => a -> a
- Clash.Explicit.Prelude.Safe: signum :: Num a => a -> a
- Clash.Explicit.Prelude.Safe: sin :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: sinh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: snd :: () => (a, b) -> b
- Clash.Explicit.Prelude.Safe: span :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Explicit.Prelude.Safe: sqrt :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: subtract :: Num a => a -> a -> a
- Clash.Explicit.Prelude.Safe: succ :: Enum a => a -> a
- Clash.Explicit.Prelude.Safe: sum :: (Foldable t, Num a) => t a -> a
- Clash.Explicit.Prelude.Safe: takeWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Explicit.Prelude.Safe: tan :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: tanh :: Floating a => a -> a
- Clash.Explicit.Prelude.Safe: toEnum :: Enum a => Int -> a
- Clash.Explicit.Prelude.Safe: toInteger :: Integral a => a -> Integer
- Clash.Explicit.Prelude.Safe: toRational :: Real a => a -> Rational
- Clash.Explicit.Prelude.Safe: traverse :: (Traversable t, Applicative f) => a -> f b -> t a -> f t b
- Clash.Explicit.Prelude.Safe: truncate :: (RealFrac a, Integral b) => a -> b
- Clash.Explicit.Prelude.Safe: type FilePath = String
- Clash.Explicit.Prelude.Safe: type IOError = IOException
- Clash.Explicit.Prelude.Safe: type Rational = Ratio Integer
- Clash.Explicit.Prelude.Safe: type ReadS a = String -> [(a, String)]
- Clash.Explicit.Prelude.Safe: type ShowS = String -> String
- Clash.Explicit.Prelude.Safe: type String = [Char]
- Clash.Explicit.Prelude.Safe: uncurry :: () => a -> b -> c -> (a, b) -> c
- Clash.Explicit.Prelude.Safe: unlines :: [String] -> String
- Clash.Explicit.Prelude.Safe: until :: () => a -> Bool -> a -> a -> a -> a
- Clash.Explicit.Prelude.Safe: unwords :: [String] -> String
- Clash.Explicit.Prelude.Safe: userError :: String -> IOError
- Clash.Explicit.Prelude.Safe: words :: String -> [String]
- Clash.Explicit.Prelude.Safe: writeFile :: FilePath -> String -> IO ()
- Clash.Explicit.Signal: Dom :: Symbol -> Nat -> Domain
- Clash.Explicit.Signal: Gated :: ClockKind
- Clash.Explicit.Signal: Source :: ClockKind
- Clash.Explicit.Signal: [clkPeriod] :: Domain -> Nat
- Clash.Explicit.Signal: [domainName] :: Domain -> Symbol
- Clash.Explicit.Signal: asyncResetGen :: Reset domain 'Asynchronous
- Clash.Explicit.Signal: clockGate :: Clock domain gated -> Signal domain Bool -> Clock domain 'Gated
- Clash.Explicit.Signal: data ClockKind
- Clash.Explicit.Signal: data Domain
- Clash.Explicit.Signal: fromSyncReset :: Reset domain 'Synchronous -> Signal domain Bool
- Clash.Explicit.Signal: syncResetGen :: (domain ~ 'Dom n clkPeriod, KnownNat clkPeriod) => Reset domain 'Synchronous
- Clash.Explicit.Signal: tbClockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Signal domain Bool -> Clock domain 'Source
- Clash.Explicit.Signal: tbSystemClockGen :: Signal System Bool -> Clock System 'Source
- Clash.Explicit.Signal: unsafeFromAsyncReset :: Reset domain 'Asynchronous -> Signal domain Bool
- Clash.Explicit.Signal: unsafeToAsyncReset :: Signal domain Bool -> Reset domain 'Asynchronous
- Clash.Explicit.Signal: unsafeToSyncReset :: Signal domain Bool -> Reset domain 'Synchronous
- Clash.Explicit.Signal.Delayed: instance Data.Default.Class.Default a => Data.Default.Class.Default (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance Data.Foldable.Foldable (Clash.Explicit.Signal.Delayed.DSignal domain delay)
- Clash.Explicit.Signal.Delayed: instance Data.Traversable.Traversable (Clash.Explicit.Signal.Delayed.DSignal domain delay)
- Clash.Explicit.Signal.Delayed: instance GHC.Base.Applicative (Clash.Explicit.Signal.Delayed.DSignal domain delay)
- Clash.Explicit.Signal.Delayed: instance GHC.Base.Functor (Clash.Explicit.Signal.Delayed.DSignal domain delay)
- Clash.Explicit.Signal.Delayed: instance GHC.Num.Num a => GHC.Num.Num (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance GHC.Real.Fractional a => GHC.Real.Fractional (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance GHC.Show.Show a => GHC.Show.Show (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance Language.Haskell.TH.Syntax.Lift a => Language.Haskell.TH.Syntax.Lift (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Explicit.Signal.Delayed: instance Test.QuickCheck.Arbitrary.CoArbitrary a => Test.QuickCheck.Arbitrary.CoArbitrary (Clash.Explicit.Signal.Delayed.DSignal domain delay a)
- Clash.Prelude: ($!) :: () => a -> b -> a -> b
- Clash.Prelude: ($) :: () => a -> b -> a -> b
- Clash.Prelude: (&&) :: Bool -> Bool -> Bool
- Clash.Prelude: (*) :: Num a => a -> a -> a
- Clash.Prelude: (**) :: Floating a => a -> a -> a
- Clash.Prelude: (*>) :: Applicative f => f a -> f b -> f b
- Clash.Prelude: (+) :: Num a => a -> a -> a
- Clash.Prelude: (-) :: Num a => a -> a -> a
- Clash.Prelude: (.) :: () => b -> c -> a -> b -> a -> c
- Clash.Prelude: (/) :: Fractional a => a -> a -> a
- Clash.Prelude: (/=) :: Eq a => a -> a -> Bool
- Clash.Prelude: (<$) :: Functor f => a -> f b -> f a
- Clash.Prelude: (<$>) :: Functor f => a -> b -> f a -> f b
- Clash.Prelude: (<) :: Ord a => a -> a -> Bool
- Clash.Prelude: (<*) :: Applicative f => f a -> f b -> f a
- Clash.Prelude: (<*>) :: Applicative f => f a -> b -> f a -> f b
- Clash.Prelude: (<=) :: Ord a => a -> a -> Bool
- Clash.Prelude: (<>) :: Semigroup a => a -> a -> a
- Clash.Prelude: (=<<) :: Monad m => a -> m b -> m a -> m b
- Clash.Prelude: (==) :: Eq a => a -> a -> Bool
- Clash.Prelude: (>) :: Ord a => a -> a -> Bool
- Clash.Prelude: (>=) :: Ord a => a -> a -> Bool
- Clash.Prelude: (>>) :: Monad m => m a -> m b -> m b
- Clash.Prelude: (>>=) :: Monad m => m a -> a -> m b -> m b
- Clash.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
- Clash.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
- Clash.Prelude: (||) :: Bool -> Bool -> Bool
- Clash.Prelude: EQ :: Ordering
- Clash.Prelude: False :: Bool
- Clash.Prelude: GT :: Ordering
- Clash.Prelude: Just :: a -> Maybe a
- Clash.Prelude: LT :: Ordering
- Clash.Prelude: Left :: a -> Either a b
- Clash.Prelude: Nothing :: Maybe a
- Clash.Prelude: Right :: b -> Either a b
- Clash.Prelude: True :: Bool
- Clash.Prelude: abs :: Num a => a -> a
- Clash.Prelude: acos :: Floating a => a -> a
- Clash.Prelude: acosh :: Floating a => a -> a
- Clash.Prelude: all :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Prelude: and :: Foldable t => t Bool -> Bool
- Clash.Prelude: any :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Prelude: appendFile :: FilePath -> String -> IO ()
- Clash.Prelude: asTypeOf :: () => a -> a -> a
- Clash.Prelude: asin :: Floating a => a -> a
- Clash.Prelude: asinh :: Floating a => a -> a
- Clash.Prelude: atan :: Floating a => a -> a
- Clash.Prelude: atan2 :: RealFloat a => a -> a -> a
- Clash.Prelude: atanh :: Floating a => a -> a
- Clash.Prelude: break :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude: class Functor f => Applicative (f :: * -> *)
- Clash.Prelude: class Bounded a
- Clash.Prelude: class Enum a
- Clash.Prelude: class Eq a
- Clash.Prelude: class Fractional a => Floating a
- Clash.Prelude: class Foldable (t :: * -> *)
- Clash.Prelude: class Num a => Fractional a
- Clash.Prelude: class Functor (f :: * -> *)
- Clash.Prelude: class (Real a, Enum a) => Integral a
- Clash.Prelude: class Applicative m => Monad (m :: * -> *)
- Clash.Prelude: class Semigroup a => Monoid a
- Clash.Prelude: class Num a
- Clash.Prelude: class Eq a => Ord a
- Clash.Prelude: class Read a
- Clash.Prelude: class (Num a, Ord a) => Real a
- Clash.Prelude: class (RealFrac a, Floating a) => RealFloat a
- Clash.Prelude: class (Real a, Fractional a) => RealFrac a
- Clash.Prelude: class Semigroup a
- Clash.Prelude: class Show a
- Clash.Prelude: class (Functor t, Foldable t) => Traversable (t :: * -> *)
- Clash.Prelude: compare :: Ord a => a -> a -> Ordering
- Clash.Prelude: concatMap :: Foldable t => a -> [b] -> t a -> [b]
- Clash.Prelude: const :: () => a -> b -> a
- Clash.Prelude: cos :: Floating a => a -> a
- Clash.Prelude: cosh :: Floating a => a -> a
- Clash.Prelude: curry :: () => (a, b) -> c -> a -> b -> c
- Clash.Prelude: cycle :: () => [a] -> [a]
- Clash.Prelude: data Bool
- Clash.Prelude: data Char
- Clash.Prelude: data Double
- Clash.Prelude: data Either a b
- Clash.Prelude: data Float
- Clash.Prelude: data IO a
- Clash.Prelude: data Int
- Clash.Prelude: data Integer
- Clash.Prelude: data Maybe a
- Clash.Prelude: data Ordering
- Clash.Prelude: data Word
- Clash.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
- Clash.Prelude: div :: Integral a => a -> a -> a
- Clash.Prelude: divMod :: Integral a => a -> a -> (a, a)
- Clash.Prelude: dropWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude: either :: () => a -> c -> b -> c -> Either a b -> c
- Clash.Prelude: elem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
- Clash.Prelude: enumFrom :: Enum a => a -> [a]
- Clash.Prelude: enumFromThen :: Enum a => a -> a -> [a]
- Clash.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- Clash.Prelude: enumFromTo :: Enum a => a -> a -> [a]
- Clash.Prelude: error :: HasCallStack => [Char] -> a
- Clash.Prelude: errorWithoutStackTrace :: () => [Char] -> a
- Clash.Prelude: even :: Integral a => a -> Bool
- Clash.Prelude: exp :: Floating a => a -> a
- Clash.Prelude: exponent :: RealFloat a => a -> Int
- Clash.Prelude: fail :: Monad m => String -> m a
- Clash.Prelude: filter :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude: flip :: () => a -> b -> c -> b -> a -> c
- Clash.Prelude: floatDigits :: RealFloat a => a -> Int
- Clash.Prelude: floatRadix :: RealFloat a => a -> Integer
- Clash.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
- Clash.Prelude: floor :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude: fmap :: Functor f => a -> b -> f a -> f b
- Clash.Prelude: foldMap :: (Foldable t, Monoid m) => a -> m -> t a -> m
- Clash.Prelude: fromEnum :: Enum a => a -> Int
- Clash.Prelude: fromInteger :: Num a => Integer -> a
- Clash.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
- Clash.Prelude: fromRational :: Fractional a => Rational -> a
- Clash.Prelude: fst :: () => (a, b) -> a
- Clash.Prelude: gcd :: Integral a => a -> a -> a
- Clash.Prelude: getChar :: IO Char
- Clash.Prelude: getContents :: IO String
- Clash.Prelude: getLine :: IO String
- Clash.Prelude: id :: () => a -> a
- Clash.Prelude: infix 4 `notElem`
- Clash.Prelude: infixl 4 <$>
- Clash.Prelude: infixr 0 $!
- Clash.Prelude: infixr 1 =<<
- Clash.Prelude: infixr 2 ||
- Clash.Prelude: infixr 8 ^
- Clash.Prelude: infixr 9 .
- Clash.Prelude: interact :: String -> String -> IO ()
- Clash.Prelude: ioError :: () => IOError -> IO a
- Clash.Prelude: isDenormalized :: RealFloat a => a -> Bool
- Clash.Prelude: isIEEE :: RealFloat a => a -> Bool
- Clash.Prelude: isInfinite :: RealFloat a => a -> Bool
- Clash.Prelude: isNaN :: RealFloat a => a -> Bool
- Clash.Prelude: isNegativeZero :: RealFloat a => a -> Bool
- Clash.Prelude: lcm :: Integral a => a -> a -> a
- Clash.Prelude: lex :: ReadS String
- Clash.Prelude: lines :: String -> [String]
- Clash.Prelude: log :: Floating a => a -> a
- Clash.Prelude: logBase :: Floating a => a -> a -> a
- Clash.Prelude: lookup :: Eq a => a -> [(a, b)] -> Maybe b
- Clash.Prelude: mapM :: (Traversable t, Monad m) => a -> m b -> t a -> m t b
- Clash.Prelude: mapM_ :: (Foldable t, Monad m) => a -> m b -> t a -> m ()
- Clash.Prelude: mappend :: Monoid a => a -> a -> a
- Clash.Prelude: max :: Ord a => a -> a -> a
- Clash.Prelude: maxBound :: Bounded a => a
- Clash.Prelude: maximum :: (Foldable t, Ord a) => t a -> a
- Clash.Prelude: maybe :: () => b -> a -> b -> Maybe a -> b
- Clash.Prelude: mconcat :: Monoid a => [a] -> a
- Clash.Prelude: mempty :: Monoid a => a
- Clash.Prelude: min :: Ord a => a -> a -> a
- Clash.Prelude: minBound :: Bounded a => a
- Clash.Prelude: minimum :: (Foldable t, Ord a) => t a -> a
- Clash.Prelude: mod :: Integral a => a -> a -> a
- Clash.Prelude: negate :: Num a => a -> a
- Clash.Prelude: not :: Bool -> Bool
- Clash.Prelude: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Prelude: null :: Foldable t => t a -> Bool
- Clash.Prelude: odd :: Integral a => a -> Bool
- Clash.Prelude: or :: Foldable t => t Bool -> Bool
- Clash.Prelude: otherwise :: Bool
- Clash.Prelude: pi :: Floating a => a
- Clash.Prelude: pred :: Enum a => a -> a
- Clash.Prelude: print :: Show a => a -> IO ()
- Clash.Prelude: product :: (Foldable t, Num a) => t a -> a
- Clash.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
- Clash.Prelude: pure :: Applicative f => a -> f a
- Clash.Prelude: putChar :: Char -> IO ()
- Clash.Prelude: putStr :: String -> IO ()
- Clash.Prelude: putStrLn :: String -> IO ()
- Clash.Prelude: quot :: Integral a => a -> a -> a
- Clash.Prelude: quotRem :: Integral a => a -> a -> (a, a)
- Clash.Prelude: read :: Read a => String -> a
- Clash.Prelude: readFile :: FilePath -> IO String
- Clash.Prelude: readIO :: Read a => String -> IO a
- Clash.Prelude: readList :: Read a => ReadS [a]
- Clash.Prelude: readLn :: Read a => IO a
- Clash.Prelude: readParen :: () => Bool -> ReadS a -> ReadS a
- Clash.Prelude: reads :: Read a => ReadS a
- Clash.Prelude: readsPrec :: Read a => Int -> ReadS a
- Clash.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
- Clash.Prelude: recip :: Fractional a => a -> a
- Clash.Prelude: rem :: Integral a => a -> a -> a
- Clash.Prelude: return :: Monad m => a -> m a
- Clash.Prelude: round :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude: scaleFloat :: RealFloat a => Int -> a -> a
- Clash.Prelude: scanl1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Prelude: scanr1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Prelude: seq :: () => a -> b -> b
- Clash.Prelude: sequence :: (Traversable t, Monad m) => t m a -> m t a
- Clash.Prelude: sequenceA :: (Traversable t, Applicative f) => t f a -> f t a
- Clash.Prelude: sequence_ :: (Foldable t, Monad m) => t m a -> m ()
- Clash.Prelude: show :: Show a => a -> String
- Clash.Prelude: showChar :: Char -> ShowS
- Clash.Prelude: showList :: Show a => [a] -> ShowS
- Clash.Prelude: showParen :: Bool -> ShowS -> ShowS
- Clash.Prelude: showString :: String -> ShowS
- Clash.Prelude: shows :: Show a => a -> ShowS
- Clash.Prelude: showsPrec :: Show a => Int -> a -> ShowS
- Clash.Prelude: significand :: RealFloat a => a -> a
- Clash.Prelude: signum :: Num a => a -> a
- Clash.Prelude: sin :: Floating a => a -> a
- Clash.Prelude: sinh :: Floating a => a -> a
- Clash.Prelude: snd :: () => (a, b) -> b
- Clash.Prelude: span :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Prelude: sqrt :: Floating a => a -> a
- Clash.Prelude: subtract :: Num a => a -> a -> a
- Clash.Prelude: succ :: Enum a => a -> a
- Clash.Prelude: sum :: (Foldable t, Num a) => t a -> a
- Clash.Prelude: takeWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude: tan :: Floating a => a -> a
- Clash.Prelude: tanh :: Floating a => a -> a
- Clash.Prelude: toEnum :: Enum a => Int -> a
- Clash.Prelude: toInteger :: Integral a => a -> Integer
- Clash.Prelude: toRational :: Real a => a -> Rational
- Clash.Prelude: traverse :: (Traversable t, Applicative f) => a -> f b -> t a -> f t b
- Clash.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude: type FilePath = String
- Clash.Prelude: type IOError = IOException
- Clash.Prelude: type Rational = Ratio Integer
- Clash.Prelude: type ReadS a = String -> [(a, String)]
- Clash.Prelude: type ShowS = String -> String
- Clash.Prelude: type String = [Char]
- Clash.Prelude: uncurry :: () => a -> b -> c -> (a, b) -> c
- Clash.Prelude: unlines :: [String] -> String
- Clash.Prelude: until :: () => a -> Bool -> a -> a -> a -> a
- Clash.Prelude: unwords :: [String] -> String
- Clash.Prelude: userError :: String -> IOError
- Clash.Prelude: words :: String -> [String]
- Clash.Prelude: writeFile :: FilePath -> String -> IO ()
- Clash.Prelude.Safe: ($!) :: () => a -> b -> a -> b
- Clash.Prelude.Safe: ($) :: () => a -> b -> a -> b
- Clash.Prelude.Safe: (&&) :: Bool -> Bool -> Bool
- Clash.Prelude.Safe: (*) :: Num a => a -> a -> a
- Clash.Prelude.Safe: (**) :: Floating a => a -> a -> a
- Clash.Prelude.Safe: (*>) :: Applicative f => f a -> f b -> f b
- Clash.Prelude.Safe: (+) :: Num a => a -> a -> a
- Clash.Prelude.Safe: (-) :: Num a => a -> a -> a
- Clash.Prelude.Safe: (.) :: () => b -> c -> a -> b -> a -> c
- Clash.Prelude.Safe: (/) :: Fractional a => a -> a -> a
- Clash.Prelude.Safe: (/=) :: Eq a => a -> a -> Bool
- Clash.Prelude.Safe: (<$) :: Functor f => a -> f b -> f a
- Clash.Prelude.Safe: (<$>) :: Functor f => a -> b -> f a -> f b
- Clash.Prelude.Safe: (<) :: Ord a => a -> a -> Bool
- Clash.Prelude.Safe: (<*) :: Applicative f => f a -> f b -> f a
- Clash.Prelude.Safe: (<*>) :: Applicative f => f a -> b -> f a -> f b
- Clash.Prelude.Safe: (<=) :: Ord a => a -> a -> Bool
- Clash.Prelude.Safe: (<>) :: Semigroup a => a -> a -> a
- Clash.Prelude.Safe: (=<<) :: Monad m => a -> m b -> m a -> m b
- Clash.Prelude.Safe: (==) :: Eq a => a -> a -> Bool
- Clash.Prelude.Safe: (>) :: Ord a => a -> a -> Bool
- Clash.Prelude.Safe: (>=) :: Ord a => a -> a -> Bool
- Clash.Prelude.Safe: (>>) :: Monad m => m a -> m b -> m b
- Clash.Prelude.Safe: (>>=) :: Monad m => m a -> a -> m b -> m b
- Clash.Prelude.Safe: (^) :: (Num a, Integral b) => a -> b -> a
- Clash.Prelude.Safe: (^^) :: (Fractional a, Integral b) => a -> b -> a
- Clash.Prelude.Safe: (||) :: Bool -> Bool -> Bool
- Clash.Prelude.Safe: EQ :: Ordering
- Clash.Prelude.Safe: False :: Bool
- Clash.Prelude.Safe: GT :: Ordering
- Clash.Prelude.Safe: Just :: a -> Maybe a
- Clash.Prelude.Safe: LT :: Ordering
- Clash.Prelude.Safe: Left :: a -> Either a b
- Clash.Prelude.Safe: Nothing :: Maybe a
- Clash.Prelude.Safe: Right :: b -> Either a b
- Clash.Prelude.Safe: True :: Bool
- Clash.Prelude.Safe: abs :: Num a => a -> a
- Clash.Prelude.Safe: acos :: Floating a => a -> a
- Clash.Prelude.Safe: acosh :: Floating a => a -> a
- Clash.Prelude.Safe: all :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Prelude.Safe: and :: Foldable t => t Bool -> Bool
- Clash.Prelude.Safe: any :: Foldable t => a -> Bool -> t a -> Bool
- Clash.Prelude.Safe: appendFile :: FilePath -> String -> IO ()
- Clash.Prelude.Safe: asTypeOf :: () => a -> a -> a
- Clash.Prelude.Safe: asin :: Floating a => a -> a
- Clash.Prelude.Safe: asinh :: Floating a => a -> a
- Clash.Prelude.Safe: atan :: Floating a => a -> a
- Clash.Prelude.Safe: atan2 :: RealFloat a => a -> a -> a
- Clash.Prelude.Safe: atanh :: Floating a => a -> a
- Clash.Prelude.Safe: break :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Prelude.Safe: ceiling :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude.Safe: class Functor f => Applicative (f :: * -> *)
- Clash.Prelude.Safe: class Bounded a
- Clash.Prelude.Safe: class Enum a
- Clash.Prelude.Safe: class Eq a
- Clash.Prelude.Safe: class Fractional a => Floating a
- Clash.Prelude.Safe: class Foldable (t :: * -> *)
- Clash.Prelude.Safe: class Num a => Fractional a
- Clash.Prelude.Safe: class Functor (f :: * -> *)
- Clash.Prelude.Safe: class (Real a, Enum a) => Integral a
- Clash.Prelude.Safe: class Applicative m => Monad (m :: * -> *)
- Clash.Prelude.Safe: class Semigroup a => Monoid a
- Clash.Prelude.Safe: class Num a
- Clash.Prelude.Safe: class Eq a => Ord a
- Clash.Prelude.Safe: class Read a
- Clash.Prelude.Safe: class (Num a, Ord a) => Real a
- Clash.Prelude.Safe: class (RealFrac a, Floating a) => RealFloat a
- Clash.Prelude.Safe: class (Real a, Fractional a) => RealFrac a
- Clash.Prelude.Safe: class Semigroup a
- Clash.Prelude.Safe: class Show a
- Clash.Prelude.Safe: class (Functor t, Foldable t) => Traversable (t :: * -> *)
- Clash.Prelude.Safe: compare :: Ord a => a -> a -> Ordering
- Clash.Prelude.Safe: concatMap :: Foldable t => a -> [b] -> t a -> [b]
- Clash.Prelude.Safe: const :: () => a -> b -> a
- Clash.Prelude.Safe: cos :: Floating a => a -> a
- Clash.Prelude.Safe: cosh :: Floating a => a -> a
- Clash.Prelude.Safe: curry :: () => (a, b) -> c -> a -> b -> c
- Clash.Prelude.Safe: cycle :: () => [a] -> [a]
- Clash.Prelude.Safe: data Bool
- Clash.Prelude.Safe: data Char
- Clash.Prelude.Safe: data Double
- Clash.Prelude.Safe: data Either a b
- Clash.Prelude.Safe: data Float
- Clash.Prelude.Safe: data IO a
- Clash.Prelude.Safe: data Int
- Clash.Prelude.Safe: data Integer
- Clash.Prelude.Safe: data Maybe a
- Clash.Prelude.Safe: data Ordering
- Clash.Prelude.Safe: data Word
- Clash.Prelude.Safe: decodeFloat :: RealFloat a => a -> (Integer, Int)
- Clash.Prelude.Safe: div :: Integral a => a -> a -> a
- Clash.Prelude.Safe: divMod :: Integral a => a -> a -> (a, a)
- Clash.Prelude.Safe: dropWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude.Safe: either :: () => a -> c -> b -> c -> Either a b -> c
- Clash.Prelude.Safe: elem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Prelude.Safe: encodeFloat :: RealFloat a => Integer -> Int -> a
- Clash.Prelude.Safe: enumFrom :: Enum a => a -> [a]
- Clash.Prelude.Safe: enumFromThen :: Enum a => a -> a -> [a]
- Clash.Prelude.Safe: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- Clash.Prelude.Safe: enumFromTo :: Enum a => a -> a -> [a]
- Clash.Prelude.Safe: error :: HasCallStack => [Char] -> a
- Clash.Prelude.Safe: errorWithoutStackTrace :: () => [Char] -> a
- Clash.Prelude.Safe: even :: Integral a => a -> Bool
- Clash.Prelude.Safe: exp :: Floating a => a -> a
- Clash.Prelude.Safe: exponent :: RealFloat a => a -> Int
- Clash.Prelude.Safe: fail :: Monad m => String -> m a
- Clash.Prelude.Safe: filter :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude.Safe: flip :: () => a -> b -> c -> b -> a -> c
- Clash.Prelude.Safe: floatDigits :: RealFloat a => a -> Int
- Clash.Prelude.Safe: floatRadix :: RealFloat a => a -> Integer
- Clash.Prelude.Safe: floatRange :: RealFloat a => a -> (Int, Int)
- Clash.Prelude.Safe: floor :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude.Safe: fmap :: Functor f => a -> b -> f a -> f b
- Clash.Prelude.Safe: foldMap :: (Foldable t, Monoid m) => a -> m -> t a -> m
- Clash.Prelude.Safe: fromEnum :: Enum a => a -> Int
- Clash.Prelude.Safe: fromInteger :: Num a => Integer -> a
- Clash.Prelude.Safe: fromIntegral :: (Integral a, Num b) => a -> b
- Clash.Prelude.Safe: fromRational :: Fractional a => Rational -> a
- Clash.Prelude.Safe: fst :: () => (a, b) -> a
- Clash.Prelude.Safe: gcd :: Integral a => a -> a -> a
- Clash.Prelude.Safe: getChar :: IO Char
- Clash.Prelude.Safe: getContents :: IO String
- Clash.Prelude.Safe: getLine :: IO String
- Clash.Prelude.Safe: id :: () => a -> a
- Clash.Prelude.Safe: infix 4 `notElem`
- Clash.Prelude.Safe: infixl 4 <$>
- Clash.Prelude.Safe: infixr 0 $!
- Clash.Prelude.Safe: infixr 1 =<<
- Clash.Prelude.Safe: infixr 2 ||
- Clash.Prelude.Safe: infixr 8 ^
- Clash.Prelude.Safe: infixr 9 .
- Clash.Prelude.Safe: interact :: String -> String -> IO ()
- Clash.Prelude.Safe: ioError :: () => IOError -> IO a
- Clash.Prelude.Safe: isDenormalized :: RealFloat a => a -> Bool
- Clash.Prelude.Safe: isIEEE :: RealFloat a => a -> Bool
- Clash.Prelude.Safe: isInfinite :: RealFloat a => a -> Bool
- Clash.Prelude.Safe: isNaN :: RealFloat a => a -> Bool
- Clash.Prelude.Safe: isNegativeZero :: RealFloat a => a -> Bool
- Clash.Prelude.Safe: lcm :: Integral a => a -> a -> a
- Clash.Prelude.Safe: lex :: ReadS String
- Clash.Prelude.Safe: lines :: String -> [String]
- Clash.Prelude.Safe: log :: Floating a => a -> a
- Clash.Prelude.Safe: logBase :: Floating a => a -> a -> a
- Clash.Prelude.Safe: lookup :: Eq a => a -> [(a, b)] -> Maybe b
- Clash.Prelude.Safe: mapM :: (Traversable t, Monad m) => a -> m b -> t a -> m t b
- Clash.Prelude.Safe: mapM_ :: (Foldable t, Monad m) => a -> m b -> t a -> m ()
- Clash.Prelude.Safe: mappend :: Monoid a => a -> a -> a
- Clash.Prelude.Safe: max :: Ord a => a -> a -> a
- Clash.Prelude.Safe: maxBound :: Bounded a => a
- Clash.Prelude.Safe: maximum :: (Foldable t, Ord a) => t a -> a
- Clash.Prelude.Safe: maybe :: () => b -> a -> b -> Maybe a -> b
- Clash.Prelude.Safe: mconcat :: Monoid a => [a] -> a
- Clash.Prelude.Safe: mempty :: Monoid a => a
- Clash.Prelude.Safe: min :: Ord a => a -> a -> a
- Clash.Prelude.Safe: minBound :: Bounded a => a
- Clash.Prelude.Safe: minimum :: (Foldable t, Ord a) => t a -> a
- Clash.Prelude.Safe: mod :: Integral a => a -> a -> a
- Clash.Prelude.Safe: negate :: Num a => a -> a
- Clash.Prelude.Safe: not :: Bool -> Bool
- Clash.Prelude.Safe: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- Clash.Prelude.Safe: null :: Foldable t => t a -> Bool
- Clash.Prelude.Safe: odd :: Integral a => a -> Bool
- Clash.Prelude.Safe: or :: Foldable t => t Bool -> Bool
- Clash.Prelude.Safe: otherwise :: Bool
- Clash.Prelude.Safe: pi :: Floating a => a
- Clash.Prelude.Safe: pred :: Enum a => a -> a
- Clash.Prelude.Safe: print :: Show a => a -> IO ()
- Clash.Prelude.Safe: product :: (Foldable t, Num a) => t a -> a
- Clash.Prelude.Safe: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
- Clash.Prelude.Safe: pure :: Applicative f => a -> f a
- Clash.Prelude.Safe: putChar :: Char -> IO ()
- Clash.Prelude.Safe: putStr :: String -> IO ()
- Clash.Prelude.Safe: putStrLn :: String -> IO ()
- Clash.Prelude.Safe: quot :: Integral a => a -> a -> a
- Clash.Prelude.Safe: quotRem :: Integral a => a -> a -> (a, a)
- Clash.Prelude.Safe: read :: Read a => String -> a
- Clash.Prelude.Safe: readFile :: FilePath -> IO String
- Clash.Prelude.Safe: readIO :: Read a => String -> IO a
- Clash.Prelude.Safe: readList :: Read a => ReadS [a]
- Clash.Prelude.Safe: readLn :: Read a => IO a
- Clash.Prelude.Safe: readParen :: () => Bool -> ReadS a -> ReadS a
- Clash.Prelude.Safe: reads :: Read a => ReadS a
- Clash.Prelude.Safe: readsPrec :: Read a => Int -> ReadS a
- Clash.Prelude.Safe: realToFrac :: (Real a, Fractional b) => a -> b
- Clash.Prelude.Safe: recip :: Fractional a => a -> a
- Clash.Prelude.Safe: rem :: Integral a => a -> a -> a
- Clash.Prelude.Safe: return :: Monad m => a -> m a
- Clash.Prelude.Safe: round :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude.Safe: scaleFloat :: RealFloat a => Int -> a -> a
- Clash.Prelude.Safe: scanl1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Prelude.Safe: scanr1 :: () => a -> a -> a -> [a] -> [a]
- Clash.Prelude.Safe: seq :: () => a -> b -> b
- Clash.Prelude.Safe: sequence :: (Traversable t, Monad m) => t m a -> m t a
- Clash.Prelude.Safe: sequenceA :: (Traversable t, Applicative f) => t f a -> f t a
- Clash.Prelude.Safe: sequence_ :: (Foldable t, Monad m) => t m a -> m ()
- Clash.Prelude.Safe: show :: Show a => a -> String
- Clash.Prelude.Safe: showChar :: Char -> ShowS
- Clash.Prelude.Safe: showList :: Show a => [a] -> ShowS
- Clash.Prelude.Safe: showParen :: Bool -> ShowS -> ShowS
- Clash.Prelude.Safe: showString :: String -> ShowS
- Clash.Prelude.Safe: shows :: Show a => a -> ShowS
- Clash.Prelude.Safe: showsPrec :: Show a => Int -> a -> ShowS
- Clash.Prelude.Safe: significand :: RealFloat a => a -> a
- Clash.Prelude.Safe: signum :: Num a => a -> a
- Clash.Prelude.Safe: sin :: Floating a => a -> a
- Clash.Prelude.Safe: sinh :: Floating a => a -> a
- Clash.Prelude.Safe: snd :: () => (a, b) -> b
- Clash.Prelude.Safe: span :: () => a -> Bool -> [a] -> ([a], [a])
- Clash.Prelude.Safe: sqrt :: Floating a => a -> a
- Clash.Prelude.Safe: subtract :: Num a => a -> a -> a
- Clash.Prelude.Safe: succ :: Enum a => a -> a
- Clash.Prelude.Safe: sum :: (Foldable t, Num a) => t a -> a
- Clash.Prelude.Safe: takeWhile :: () => a -> Bool -> [a] -> [a]
- Clash.Prelude.Safe: tan :: Floating a => a -> a
- Clash.Prelude.Safe: tanh :: Floating a => a -> a
- Clash.Prelude.Safe: toEnum :: Enum a => Int -> a
- Clash.Prelude.Safe: toInteger :: Integral a => a -> Integer
- Clash.Prelude.Safe: toRational :: Real a => a -> Rational
- Clash.Prelude.Safe: traverse :: (Traversable t, Applicative f) => a -> f b -> t a -> f t b
- Clash.Prelude.Safe: truncate :: (RealFrac a, Integral b) => a -> b
- Clash.Prelude.Safe: type FilePath = String
- Clash.Prelude.Safe: type IOError = IOException
- Clash.Prelude.Safe: type Rational = Ratio Integer
- Clash.Prelude.Safe: type ReadS a = String -> [(a, String)]
- Clash.Prelude.Safe: type ShowS = String -> String
- Clash.Prelude.Safe: type String = [Char]
- Clash.Prelude.Safe: uncurry :: () => a -> b -> c -> (a, b) -> c
- Clash.Prelude.Safe: unlines :: [String] -> String
- Clash.Prelude.Safe: until :: () => a -> Bool -> a -> a -> a -> a
- Clash.Prelude.Safe: unwords :: [String] -> String
- Clash.Prelude.Safe: userError :: String -> IOError
- Clash.Prelude.Safe: words :: String -> [String]
- Clash.Prelude.Safe: writeFile :: FilePath -> String -> IO ()
- Clash.Prelude.Testbench: outputVerifier :: (KnownNat l, Eq a, ShowX a, HiddenClockReset domain gated synchronous) => Vec l a -> Signal domain a -> Signal domain Bool
- Clash.Promoted.Nat: plusToLe :: forall (k :: Nat) n f r. f (n + k) -> (forall m. (k <= m) => f m -> r) -> r
- Clash.Promoted.Nat: plusToLeKN :: forall (k :: Nat) n f r. (KnownNat n, KnownNat k) => f (n + k) -> (forall m. (KnownNat m, k <= m) => f m -> r) -> r
- Clash.Promoted.Nat.Literals: d0 :: SNat 0
- Clash.Promoted.Nat.Literals: d1 :: SNat 1
- Clash.Promoted.Nat.Literals: d10 :: SNat 10
- Clash.Promoted.Nat.Literals: d100 :: SNat 100
- Clash.Promoted.Nat.Literals: d1000 :: SNat 1000
- Clash.Promoted.Nat.Literals: d1001 :: SNat 1001
- Clash.Promoted.Nat.Literals: d1002 :: SNat 1002
- Clash.Promoted.Nat.Literals: d1003 :: SNat 1003
- Clash.Promoted.Nat.Literals: d1004 :: SNat 1004
- Clash.Promoted.Nat.Literals: d1005 :: SNat 1005
- Clash.Promoted.Nat.Literals: d1006 :: SNat 1006
- Clash.Promoted.Nat.Literals: d1007 :: SNat 1007
- Clash.Promoted.Nat.Literals: d1008 :: SNat 1008
- Clash.Promoted.Nat.Literals: d1009 :: SNat 1009
- Clash.Promoted.Nat.Literals: d101 :: SNat 101
- Clash.Promoted.Nat.Literals: d1010 :: SNat 1010
- Clash.Promoted.Nat.Literals: d1011 :: SNat 1011
- Clash.Promoted.Nat.Literals: d1012 :: SNat 1012
- Clash.Promoted.Nat.Literals: d1013 :: SNat 1013
- Clash.Promoted.Nat.Literals: d1014 :: SNat 1014
- Clash.Promoted.Nat.Literals: d1015 :: SNat 1015
- Clash.Promoted.Nat.Literals: d1016 :: SNat 1016
- Clash.Promoted.Nat.Literals: d1017 :: SNat 1017
- Clash.Promoted.Nat.Literals: d1018 :: SNat 1018
- Clash.Promoted.Nat.Literals: d1019 :: SNat 1019
- Clash.Promoted.Nat.Literals: d102 :: SNat 102
- Clash.Promoted.Nat.Literals: d1020 :: SNat 1020
- Clash.Promoted.Nat.Literals: d1021 :: SNat 1021
- Clash.Promoted.Nat.Literals: d1022 :: SNat 1022
- Clash.Promoted.Nat.Literals: d1023 :: SNat 1023
- Clash.Promoted.Nat.Literals: d1024 :: SNat 1024
- Clash.Promoted.Nat.Literals: d103 :: SNat 103
- Clash.Promoted.Nat.Literals: d104 :: SNat 104
- Clash.Promoted.Nat.Literals: d105 :: SNat 105
- Clash.Promoted.Nat.Literals: d106 :: SNat 106
- Clash.Promoted.Nat.Literals: d107 :: SNat 107
- Clash.Promoted.Nat.Literals: d108 :: SNat 108
- Clash.Promoted.Nat.Literals: d109 :: SNat 109
- Clash.Promoted.Nat.Literals: d11 :: SNat 11
- Clash.Promoted.Nat.Literals: d110 :: SNat 110
- Clash.Promoted.Nat.Literals: d111 :: SNat 111
- Clash.Promoted.Nat.Literals: d112 :: SNat 112
- Clash.Promoted.Nat.Literals: d113 :: SNat 113
- Clash.Promoted.Nat.Literals: d114 :: SNat 114
- Clash.Promoted.Nat.Literals: d115 :: SNat 115
- Clash.Promoted.Nat.Literals: d116 :: SNat 116
- Clash.Promoted.Nat.Literals: d117 :: SNat 117
- Clash.Promoted.Nat.Literals: d118 :: SNat 118
- Clash.Promoted.Nat.Literals: d119 :: SNat 119
- Clash.Promoted.Nat.Literals: d12 :: SNat 12
- Clash.Promoted.Nat.Literals: d120 :: SNat 120
- Clash.Promoted.Nat.Literals: d121 :: SNat 121
- Clash.Promoted.Nat.Literals: d122 :: SNat 122
- Clash.Promoted.Nat.Literals: d123 :: SNat 123
- Clash.Promoted.Nat.Literals: d124 :: SNat 124
- Clash.Promoted.Nat.Literals: d125 :: SNat 125
- Clash.Promoted.Nat.Literals: d126 :: SNat 126
- Clash.Promoted.Nat.Literals: d127 :: SNat 127
- Clash.Promoted.Nat.Literals: d128 :: SNat 128
- Clash.Promoted.Nat.Literals: d129 :: SNat 129
- Clash.Promoted.Nat.Literals: d13 :: SNat 13
- Clash.Promoted.Nat.Literals: d130 :: SNat 130
- Clash.Promoted.Nat.Literals: d131 :: SNat 131
- Clash.Promoted.Nat.Literals: d132 :: SNat 132
- Clash.Promoted.Nat.Literals: d133 :: SNat 133
- Clash.Promoted.Nat.Literals: d134 :: SNat 134
- Clash.Promoted.Nat.Literals: d135 :: SNat 135
- Clash.Promoted.Nat.Literals: d136 :: SNat 136
- Clash.Promoted.Nat.Literals: d137 :: SNat 137
- Clash.Promoted.Nat.Literals: d138 :: SNat 138
- Clash.Promoted.Nat.Literals: d139 :: SNat 139
- Clash.Promoted.Nat.Literals: d14 :: SNat 14
- Clash.Promoted.Nat.Literals: d140 :: SNat 140
- Clash.Promoted.Nat.Literals: d141 :: SNat 141
- Clash.Promoted.Nat.Literals: d142 :: SNat 142
- Clash.Promoted.Nat.Literals: d143 :: SNat 143
- Clash.Promoted.Nat.Literals: d144 :: SNat 144
- Clash.Promoted.Nat.Literals: d145 :: SNat 145
- Clash.Promoted.Nat.Literals: d146 :: SNat 146
- Clash.Promoted.Nat.Literals: d147 :: SNat 147
- Clash.Promoted.Nat.Literals: d148 :: SNat 148
- Clash.Promoted.Nat.Literals: d149 :: SNat 149
- Clash.Promoted.Nat.Literals: d15 :: SNat 15
- Clash.Promoted.Nat.Literals: d150 :: SNat 150
- Clash.Promoted.Nat.Literals: d151 :: SNat 151
- Clash.Promoted.Nat.Literals: d152 :: SNat 152
- Clash.Promoted.Nat.Literals: d153 :: SNat 153
- Clash.Promoted.Nat.Literals: d154 :: SNat 154
- Clash.Promoted.Nat.Literals: d155 :: SNat 155
- Clash.Promoted.Nat.Literals: d156 :: SNat 156
- Clash.Promoted.Nat.Literals: d157 :: SNat 157
- Clash.Promoted.Nat.Literals: d158 :: SNat 158
- Clash.Promoted.Nat.Literals: d159 :: SNat 159
- Clash.Promoted.Nat.Literals: d16 :: SNat 16
- Clash.Promoted.Nat.Literals: d160 :: SNat 160
- Clash.Promoted.Nat.Literals: d161 :: SNat 161
- Clash.Promoted.Nat.Literals: d162 :: SNat 162
- Clash.Promoted.Nat.Literals: d163 :: SNat 163
- Clash.Promoted.Nat.Literals: d164 :: SNat 164
- Clash.Promoted.Nat.Literals: d165 :: SNat 165
- Clash.Promoted.Nat.Literals: d166 :: SNat 166
- Clash.Promoted.Nat.Literals: d167 :: SNat 167
- Clash.Promoted.Nat.Literals: d168 :: SNat 168
- Clash.Promoted.Nat.Literals: d169 :: SNat 169
- Clash.Promoted.Nat.Literals: d17 :: SNat 17
- Clash.Promoted.Nat.Literals: d170 :: SNat 170
- Clash.Promoted.Nat.Literals: d171 :: SNat 171
- Clash.Promoted.Nat.Literals: d172 :: SNat 172
- Clash.Promoted.Nat.Literals: d173 :: SNat 173
- Clash.Promoted.Nat.Literals: d174 :: SNat 174
- Clash.Promoted.Nat.Literals: d175 :: SNat 175
- Clash.Promoted.Nat.Literals: d176 :: SNat 176
- Clash.Promoted.Nat.Literals: d177 :: SNat 177
- Clash.Promoted.Nat.Literals: d178 :: SNat 178
- Clash.Promoted.Nat.Literals: d179 :: SNat 179
- Clash.Promoted.Nat.Literals: d18 :: SNat 18
- Clash.Promoted.Nat.Literals: d180 :: SNat 180
- Clash.Promoted.Nat.Literals: d181 :: SNat 181
- Clash.Promoted.Nat.Literals: d182 :: SNat 182
- Clash.Promoted.Nat.Literals: d183 :: SNat 183
- Clash.Promoted.Nat.Literals: d184 :: SNat 184
- Clash.Promoted.Nat.Literals: d185 :: SNat 185
- Clash.Promoted.Nat.Literals: d186 :: SNat 186
- Clash.Promoted.Nat.Literals: d187 :: SNat 187
- Clash.Promoted.Nat.Literals: d188 :: SNat 188
- Clash.Promoted.Nat.Literals: d189 :: SNat 189
- Clash.Promoted.Nat.Literals: d19 :: SNat 19
- Clash.Promoted.Nat.Literals: d190 :: SNat 190
- Clash.Promoted.Nat.Literals: d191 :: SNat 191
- Clash.Promoted.Nat.Literals: d192 :: SNat 192
- Clash.Promoted.Nat.Literals: d193 :: SNat 193
- Clash.Promoted.Nat.Literals: d194 :: SNat 194
- Clash.Promoted.Nat.Literals: d195 :: SNat 195
- Clash.Promoted.Nat.Literals: d196 :: SNat 196
- Clash.Promoted.Nat.Literals: d197 :: SNat 197
- Clash.Promoted.Nat.Literals: d198 :: SNat 198
- Clash.Promoted.Nat.Literals: d199 :: SNat 199
- Clash.Promoted.Nat.Literals: d2 :: SNat 2
- Clash.Promoted.Nat.Literals: d20 :: SNat 20
- Clash.Promoted.Nat.Literals: d200 :: SNat 200
- Clash.Promoted.Nat.Literals: d201 :: SNat 201
- Clash.Promoted.Nat.Literals: d202 :: SNat 202
- Clash.Promoted.Nat.Literals: d203 :: SNat 203
- Clash.Promoted.Nat.Literals: d204 :: SNat 204
- Clash.Promoted.Nat.Literals: d205 :: SNat 205
- Clash.Promoted.Nat.Literals: d206 :: SNat 206
- Clash.Promoted.Nat.Literals: d207 :: SNat 207
- Clash.Promoted.Nat.Literals: d208 :: SNat 208
- Clash.Promoted.Nat.Literals: d209 :: SNat 209
- Clash.Promoted.Nat.Literals: d21 :: SNat 21
- Clash.Promoted.Nat.Literals: d210 :: SNat 210
- Clash.Promoted.Nat.Literals: d211 :: SNat 211
- Clash.Promoted.Nat.Literals: d212 :: SNat 212
- Clash.Promoted.Nat.Literals: d213 :: SNat 213
- Clash.Promoted.Nat.Literals: d214 :: SNat 214
- Clash.Promoted.Nat.Literals: d215 :: SNat 215
- Clash.Promoted.Nat.Literals: d216 :: SNat 216
- Clash.Promoted.Nat.Literals: d217 :: SNat 217
- Clash.Promoted.Nat.Literals: d218 :: SNat 218
- Clash.Promoted.Nat.Literals: d219 :: SNat 219
- Clash.Promoted.Nat.Literals: d22 :: SNat 22
- Clash.Promoted.Nat.Literals: d220 :: SNat 220
- Clash.Promoted.Nat.Literals: d221 :: SNat 221
- Clash.Promoted.Nat.Literals: d222 :: SNat 222
- Clash.Promoted.Nat.Literals: d223 :: SNat 223
- Clash.Promoted.Nat.Literals: d224 :: SNat 224
- Clash.Promoted.Nat.Literals: d225 :: SNat 225
- Clash.Promoted.Nat.Literals: d226 :: SNat 226
- Clash.Promoted.Nat.Literals: d227 :: SNat 227
- Clash.Promoted.Nat.Literals: d228 :: SNat 228
- Clash.Promoted.Nat.Literals: d229 :: SNat 229
- Clash.Promoted.Nat.Literals: d23 :: SNat 23
- Clash.Promoted.Nat.Literals: d230 :: SNat 230
- Clash.Promoted.Nat.Literals: d231 :: SNat 231
- Clash.Promoted.Nat.Literals: d232 :: SNat 232
- Clash.Promoted.Nat.Literals: d233 :: SNat 233
- Clash.Promoted.Nat.Literals: d234 :: SNat 234
- Clash.Promoted.Nat.Literals: d235 :: SNat 235
- Clash.Promoted.Nat.Literals: d236 :: SNat 236
- Clash.Promoted.Nat.Literals: d237 :: SNat 237
- Clash.Promoted.Nat.Literals: d238 :: SNat 238
- Clash.Promoted.Nat.Literals: d239 :: SNat 239
- Clash.Promoted.Nat.Literals: d24 :: SNat 24
- Clash.Promoted.Nat.Literals: d240 :: SNat 240
- Clash.Promoted.Nat.Literals: d241 :: SNat 241
- Clash.Promoted.Nat.Literals: d242 :: SNat 242
- Clash.Promoted.Nat.Literals: d243 :: SNat 243
- Clash.Promoted.Nat.Literals: d244 :: SNat 244
- Clash.Promoted.Nat.Literals: d245 :: SNat 245
- Clash.Promoted.Nat.Literals: d246 :: SNat 246
- Clash.Promoted.Nat.Literals: d247 :: SNat 247
- Clash.Promoted.Nat.Literals: d248 :: SNat 248
- Clash.Promoted.Nat.Literals: d249 :: SNat 249
- Clash.Promoted.Nat.Literals: d25 :: SNat 25
- Clash.Promoted.Nat.Literals: d250 :: SNat 250
- Clash.Promoted.Nat.Literals: d251 :: SNat 251
- Clash.Promoted.Nat.Literals: d252 :: SNat 252
- Clash.Promoted.Nat.Literals: d253 :: SNat 253
- Clash.Promoted.Nat.Literals: d254 :: SNat 254
- Clash.Promoted.Nat.Literals: d255 :: SNat 255
- Clash.Promoted.Nat.Literals: d256 :: SNat 256
- Clash.Promoted.Nat.Literals: d257 :: SNat 257
- Clash.Promoted.Nat.Literals: d258 :: SNat 258
- Clash.Promoted.Nat.Literals: d259 :: SNat 259
- Clash.Promoted.Nat.Literals: d26 :: SNat 26
- Clash.Promoted.Nat.Literals: d260 :: SNat 260
- Clash.Promoted.Nat.Literals: d261 :: SNat 261
- Clash.Promoted.Nat.Literals: d262 :: SNat 262
- Clash.Promoted.Nat.Literals: d263 :: SNat 263
- Clash.Promoted.Nat.Literals: d264 :: SNat 264
- Clash.Promoted.Nat.Literals: d265 :: SNat 265
- Clash.Promoted.Nat.Literals: d266 :: SNat 266
- Clash.Promoted.Nat.Literals: d267 :: SNat 267
- Clash.Promoted.Nat.Literals: d268 :: SNat 268
- Clash.Promoted.Nat.Literals: d269 :: SNat 269
- Clash.Promoted.Nat.Literals: d27 :: SNat 27
- Clash.Promoted.Nat.Literals: d270 :: SNat 270
- Clash.Promoted.Nat.Literals: d271 :: SNat 271
- Clash.Promoted.Nat.Literals: d272 :: SNat 272
- Clash.Promoted.Nat.Literals: d273 :: SNat 273
- Clash.Promoted.Nat.Literals: d274 :: SNat 274
- Clash.Promoted.Nat.Literals: d275 :: SNat 275
- Clash.Promoted.Nat.Literals: d276 :: SNat 276
- Clash.Promoted.Nat.Literals: d277 :: SNat 277
- Clash.Promoted.Nat.Literals: d278 :: SNat 278
- Clash.Promoted.Nat.Literals: d279 :: SNat 279
- Clash.Promoted.Nat.Literals: d28 :: SNat 28
- Clash.Promoted.Nat.Literals: d280 :: SNat 280
- Clash.Promoted.Nat.Literals: d281 :: SNat 281
- Clash.Promoted.Nat.Literals: d282 :: SNat 282
- Clash.Promoted.Nat.Literals: d283 :: SNat 283
- Clash.Promoted.Nat.Literals: d284 :: SNat 284
- Clash.Promoted.Nat.Literals: d285 :: SNat 285
- Clash.Promoted.Nat.Literals: d286 :: SNat 286
- Clash.Promoted.Nat.Literals: d287 :: SNat 287
- Clash.Promoted.Nat.Literals: d288 :: SNat 288
- Clash.Promoted.Nat.Literals: d289 :: SNat 289
- Clash.Promoted.Nat.Literals: d29 :: SNat 29
- Clash.Promoted.Nat.Literals: d290 :: SNat 290
- Clash.Promoted.Nat.Literals: d291 :: SNat 291
- Clash.Promoted.Nat.Literals: d292 :: SNat 292
- Clash.Promoted.Nat.Literals: d293 :: SNat 293
- Clash.Promoted.Nat.Literals: d294 :: SNat 294
- Clash.Promoted.Nat.Literals: d295 :: SNat 295
- Clash.Promoted.Nat.Literals: d296 :: SNat 296
- Clash.Promoted.Nat.Literals: d297 :: SNat 297
- Clash.Promoted.Nat.Literals: d298 :: SNat 298
- Clash.Promoted.Nat.Literals: d299 :: SNat 299
- Clash.Promoted.Nat.Literals: d3 :: SNat 3
- Clash.Promoted.Nat.Literals: d30 :: SNat 30
- Clash.Promoted.Nat.Literals: d300 :: SNat 300
- Clash.Promoted.Nat.Literals: d301 :: SNat 301
- Clash.Promoted.Nat.Literals: d302 :: SNat 302
- Clash.Promoted.Nat.Literals: d303 :: SNat 303
- Clash.Promoted.Nat.Literals: d304 :: SNat 304
- Clash.Promoted.Nat.Literals: d305 :: SNat 305
- Clash.Promoted.Nat.Literals: d306 :: SNat 306
- Clash.Promoted.Nat.Literals: d307 :: SNat 307
- Clash.Promoted.Nat.Literals: d308 :: SNat 308
- Clash.Promoted.Nat.Literals: d309 :: SNat 309
- Clash.Promoted.Nat.Literals: d31 :: SNat 31
- Clash.Promoted.Nat.Literals: d310 :: SNat 310
- Clash.Promoted.Nat.Literals: d311 :: SNat 311
- Clash.Promoted.Nat.Literals: d312 :: SNat 312
- Clash.Promoted.Nat.Literals: d313 :: SNat 313
- Clash.Promoted.Nat.Literals: d314 :: SNat 314
- Clash.Promoted.Nat.Literals: d315 :: SNat 315
- Clash.Promoted.Nat.Literals: d316 :: SNat 316
- Clash.Promoted.Nat.Literals: d317 :: SNat 317
- Clash.Promoted.Nat.Literals: d318 :: SNat 318
- Clash.Promoted.Nat.Literals: d319 :: SNat 319
- Clash.Promoted.Nat.Literals: d32 :: SNat 32
- Clash.Promoted.Nat.Literals: d320 :: SNat 320
- Clash.Promoted.Nat.Literals: d321 :: SNat 321
- Clash.Promoted.Nat.Literals: d322 :: SNat 322
- Clash.Promoted.Nat.Literals: d323 :: SNat 323
- Clash.Promoted.Nat.Literals: d324 :: SNat 324
- Clash.Promoted.Nat.Literals: d325 :: SNat 325
- Clash.Promoted.Nat.Literals: d326 :: SNat 326
- Clash.Promoted.Nat.Literals: d327 :: SNat 327
- Clash.Promoted.Nat.Literals: d328 :: SNat 328
- Clash.Promoted.Nat.Literals: d329 :: SNat 329
- Clash.Promoted.Nat.Literals: d33 :: SNat 33
- Clash.Promoted.Nat.Literals: d330 :: SNat 330
- Clash.Promoted.Nat.Literals: d331 :: SNat 331
- Clash.Promoted.Nat.Literals: d332 :: SNat 332
- Clash.Promoted.Nat.Literals: d333 :: SNat 333
- Clash.Promoted.Nat.Literals: d334 :: SNat 334
- Clash.Promoted.Nat.Literals: d335 :: SNat 335
- Clash.Promoted.Nat.Literals: d336 :: SNat 336
- Clash.Promoted.Nat.Literals: d337 :: SNat 337
- Clash.Promoted.Nat.Literals: d338 :: SNat 338
- Clash.Promoted.Nat.Literals: d339 :: SNat 339
- Clash.Promoted.Nat.Literals: d34 :: SNat 34
- Clash.Promoted.Nat.Literals: d340 :: SNat 340
- Clash.Promoted.Nat.Literals: d341 :: SNat 341
- Clash.Promoted.Nat.Literals: d342 :: SNat 342
- Clash.Promoted.Nat.Literals: d343 :: SNat 343
- Clash.Promoted.Nat.Literals: d344 :: SNat 344
- Clash.Promoted.Nat.Literals: d345 :: SNat 345
- Clash.Promoted.Nat.Literals: d346 :: SNat 346
- Clash.Promoted.Nat.Literals: d347 :: SNat 347
- Clash.Promoted.Nat.Literals: d348 :: SNat 348
- Clash.Promoted.Nat.Literals: d349 :: SNat 349
- Clash.Promoted.Nat.Literals: d35 :: SNat 35
- Clash.Promoted.Nat.Literals: d350 :: SNat 350
- Clash.Promoted.Nat.Literals: d351 :: SNat 351
- Clash.Promoted.Nat.Literals: d352 :: SNat 352
- Clash.Promoted.Nat.Literals: d353 :: SNat 353
- Clash.Promoted.Nat.Literals: d354 :: SNat 354
- Clash.Promoted.Nat.Literals: d355 :: SNat 355
- Clash.Promoted.Nat.Literals: d356 :: SNat 356
- Clash.Promoted.Nat.Literals: d357 :: SNat 357
- Clash.Promoted.Nat.Literals: d358 :: SNat 358
- Clash.Promoted.Nat.Literals: d359 :: SNat 359
- Clash.Promoted.Nat.Literals: d36 :: SNat 36
- Clash.Promoted.Nat.Literals: d360 :: SNat 360
- Clash.Promoted.Nat.Literals: d361 :: SNat 361
- Clash.Promoted.Nat.Literals: d362 :: SNat 362
- Clash.Promoted.Nat.Literals: d363 :: SNat 363
- Clash.Promoted.Nat.Literals: d364 :: SNat 364
- Clash.Promoted.Nat.Literals: d365 :: SNat 365
- Clash.Promoted.Nat.Literals: d366 :: SNat 366
- Clash.Promoted.Nat.Literals: d367 :: SNat 367
- Clash.Promoted.Nat.Literals: d368 :: SNat 368
- Clash.Promoted.Nat.Literals: d369 :: SNat 369
- Clash.Promoted.Nat.Literals: d37 :: SNat 37
- Clash.Promoted.Nat.Literals: d370 :: SNat 370
- Clash.Promoted.Nat.Literals: d371 :: SNat 371
- Clash.Promoted.Nat.Literals: d372 :: SNat 372
- Clash.Promoted.Nat.Literals: d373 :: SNat 373
- Clash.Promoted.Nat.Literals: d374 :: SNat 374
- Clash.Promoted.Nat.Literals: d375 :: SNat 375
- Clash.Promoted.Nat.Literals: d376 :: SNat 376
- Clash.Promoted.Nat.Literals: d377 :: SNat 377
- Clash.Promoted.Nat.Literals: d378 :: SNat 378
- Clash.Promoted.Nat.Literals: d379 :: SNat 379
- Clash.Promoted.Nat.Literals: d38 :: SNat 38
- Clash.Promoted.Nat.Literals: d380 :: SNat 380
- Clash.Promoted.Nat.Literals: d381 :: SNat 381
- Clash.Promoted.Nat.Literals: d382 :: SNat 382
- Clash.Promoted.Nat.Literals: d383 :: SNat 383
- Clash.Promoted.Nat.Literals: d384 :: SNat 384
- Clash.Promoted.Nat.Literals: d385 :: SNat 385
- Clash.Promoted.Nat.Literals: d386 :: SNat 386
- Clash.Promoted.Nat.Literals: d387 :: SNat 387
- Clash.Promoted.Nat.Literals: d388 :: SNat 388
- Clash.Promoted.Nat.Literals: d389 :: SNat 389
- Clash.Promoted.Nat.Literals: d39 :: SNat 39
- Clash.Promoted.Nat.Literals: d390 :: SNat 390
- Clash.Promoted.Nat.Literals: d391 :: SNat 391
- Clash.Promoted.Nat.Literals: d392 :: SNat 392
- Clash.Promoted.Nat.Literals: d393 :: SNat 393
- Clash.Promoted.Nat.Literals: d394 :: SNat 394
- Clash.Promoted.Nat.Literals: d395 :: SNat 395
- Clash.Promoted.Nat.Literals: d396 :: SNat 396
- Clash.Promoted.Nat.Literals: d397 :: SNat 397
- Clash.Promoted.Nat.Literals: d398 :: SNat 398
- Clash.Promoted.Nat.Literals: d399 :: SNat 399
- Clash.Promoted.Nat.Literals: d4 :: SNat 4
- Clash.Promoted.Nat.Literals: d40 :: SNat 40
- Clash.Promoted.Nat.Literals: d400 :: SNat 400
- Clash.Promoted.Nat.Literals: d401 :: SNat 401
- Clash.Promoted.Nat.Literals: d402 :: SNat 402
- Clash.Promoted.Nat.Literals: d403 :: SNat 403
- Clash.Promoted.Nat.Literals: d404 :: SNat 404
- Clash.Promoted.Nat.Literals: d405 :: SNat 405
- Clash.Promoted.Nat.Literals: d406 :: SNat 406
- Clash.Promoted.Nat.Literals: d407 :: SNat 407
- Clash.Promoted.Nat.Literals: d408 :: SNat 408
- Clash.Promoted.Nat.Literals: d409 :: SNat 409
- Clash.Promoted.Nat.Literals: d41 :: SNat 41
- Clash.Promoted.Nat.Literals: d410 :: SNat 410
- Clash.Promoted.Nat.Literals: d411 :: SNat 411
- Clash.Promoted.Nat.Literals: d412 :: SNat 412
- Clash.Promoted.Nat.Literals: d413 :: SNat 413
- Clash.Promoted.Nat.Literals: d414 :: SNat 414
- Clash.Promoted.Nat.Literals: d415 :: SNat 415
- Clash.Promoted.Nat.Literals: d416 :: SNat 416
- Clash.Promoted.Nat.Literals: d417 :: SNat 417
- Clash.Promoted.Nat.Literals: d418 :: SNat 418
- Clash.Promoted.Nat.Literals: d419 :: SNat 419
- Clash.Promoted.Nat.Literals: d42 :: SNat 42
- Clash.Promoted.Nat.Literals: d420 :: SNat 420
- Clash.Promoted.Nat.Literals: d421 :: SNat 421
- Clash.Promoted.Nat.Literals: d422 :: SNat 422
- Clash.Promoted.Nat.Literals: d423 :: SNat 423
- Clash.Promoted.Nat.Literals: d424 :: SNat 424
- Clash.Promoted.Nat.Literals: d425 :: SNat 425
- Clash.Promoted.Nat.Literals: d426 :: SNat 426
- Clash.Promoted.Nat.Literals: d427 :: SNat 427
- Clash.Promoted.Nat.Literals: d428 :: SNat 428
- Clash.Promoted.Nat.Literals: d429 :: SNat 429
- Clash.Promoted.Nat.Literals: d43 :: SNat 43
- Clash.Promoted.Nat.Literals: d430 :: SNat 430
- Clash.Promoted.Nat.Literals: d431 :: SNat 431
- Clash.Promoted.Nat.Literals: d432 :: SNat 432
- Clash.Promoted.Nat.Literals: d433 :: SNat 433
- Clash.Promoted.Nat.Literals: d434 :: SNat 434
- Clash.Promoted.Nat.Literals: d435 :: SNat 435
- Clash.Promoted.Nat.Literals: d436 :: SNat 436
- Clash.Promoted.Nat.Literals: d437 :: SNat 437
- Clash.Promoted.Nat.Literals: d438 :: SNat 438
- Clash.Promoted.Nat.Literals: d439 :: SNat 439
- Clash.Promoted.Nat.Literals: d44 :: SNat 44
- Clash.Promoted.Nat.Literals: d440 :: SNat 440
- Clash.Promoted.Nat.Literals: d441 :: SNat 441
- Clash.Promoted.Nat.Literals: d442 :: SNat 442
- Clash.Promoted.Nat.Literals: d443 :: SNat 443
- Clash.Promoted.Nat.Literals: d444 :: SNat 444
- Clash.Promoted.Nat.Literals: d445 :: SNat 445
- Clash.Promoted.Nat.Literals: d446 :: SNat 446
- Clash.Promoted.Nat.Literals: d447 :: SNat 447
- Clash.Promoted.Nat.Literals: d448 :: SNat 448
- Clash.Promoted.Nat.Literals: d449 :: SNat 449
- Clash.Promoted.Nat.Literals: d45 :: SNat 45
- Clash.Promoted.Nat.Literals: d450 :: SNat 450
- Clash.Promoted.Nat.Literals: d451 :: SNat 451
- Clash.Promoted.Nat.Literals: d452 :: SNat 452
- Clash.Promoted.Nat.Literals: d453 :: SNat 453
- Clash.Promoted.Nat.Literals: d454 :: SNat 454
- Clash.Promoted.Nat.Literals: d455 :: SNat 455
- Clash.Promoted.Nat.Literals: d456 :: SNat 456
- Clash.Promoted.Nat.Literals: d457 :: SNat 457
- Clash.Promoted.Nat.Literals: d458 :: SNat 458
- Clash.Promoted.Nat.Literals: d459 :: SNat 459
- Clash.Promoted.Nat.Literals: d46 :: SNat 46
- Clash.Promoted.Nat.Literals: d460 :: SNat 460
- Clash.Promoted.Nat.Literals: d461 :: SNat 461
- Clash.Promoted.Nat.Literals: d462 :: SNat 462
- Clash.Promoted.Nat.Literals: d463 :: SNat 463
- Clash.Promoted.Nat.Literals: d464 :: SNat 464
- Clash.Promoted.Nat.Literals: d465 :: SNat 465
- Clash.Promoted.Nat.Literals: d466 :: SNat 466
- Clash.Promoted.Nat.Literals: d467 :: SNat 467
- Clash.Promoted.Nat.Literals: d468 :: SNat 468
- Clash.Promoted.Nat.Literals: d469 :: SNat 469
- Clash.Promoted.Nat.Literals: d47 :: SNat 47
- Clash.Promoted.Nat.Literals: d470 :: SNat 470
- Clash.Promoted.Nat.Literals: d471 :: SNat 471
- Clash.Promoted.Nat.Literals: d472 :: SNat 472
- Clash.Promoted.Nat.Literals: d473 :: SNat 473
- Clash.Promoted.Nat.Literals: d474 :: SNat 474
- Clash.Promoted.Nat.Literals: d475 :: SNat 475
- Clash.Promoted.Nat.Literals: d476 :: SNat 476
- Clash.Promoted.Nat.Literals: d477 :: SNat 477
- Clash.Promoted.Nat.Literals: d478 :: SNat 478
- Clash.Promoted.Nat.Literals: d479 :: SNat 479
- Clash.Promoted.Nat.Literals: d48 :: SNat 48
- Clash.Promoted.Nat.Literals: d480 :: SNat 480
- Clash.Promoted.Nat.Literals: d481 :: SNat 481
- Clash.Promoted.Nat.Literals: d482 :: SNat 482
- Clash.Promoted.Nat.Literals: d483 :: SNat 483
- Clash.Promoted.Nat.Literals: d484 :: SNat 484
- Clash.Promoted.Nat.Literals: d485 :: SNat 485
- Clash.Promoted.Nat.Literals: d486 :: SNat 486
- Clash.Promoted.Nat.Literals: d487 :: SNat 487
- Clash.Promoted.Nat.Literals: d488 :: SNat 488
- Clash.Promoted.Nat.Literals: d489 :: SNat 489
- Clash.Promoted.Nat.Literals: d49 :: SNat 49
- Clash.Promoted.Nat.Literals: d490 :: SNat 490
- Clash.Promoted.Nat.Literals: d491 :: SNat 491
- Clash.Promoted.Nat.Literals: d492 :: SNat 492
- Clash.Promoted.Nat.Literals: d493 :: SNat 493
- Clash.Promoted.Nat.Literals: d494 :: SNat 494
- Clash.Promoted.Nat.Literals: d495 :: SNat 495
- Clash.Promoted.Nat.Literals: d496 :: SNat 496
- Clash.Promoted.Nat.Literals: d497 :: SNat 497
- Clash.Promoted.Nat.Literals: d498 :: SNat 498
- Clash.Promoted.Nat.Literals: d499 :: SNat 499
- Clash.Promoted.Nat.Literals: d5 :: SNat 5
- Clash.Promoted.Nat.Literals: d50 :: SNat 50
- Clash.Promoted.Nat.Literals: d500 :: SNat 500
- Clash.Promoted.Nat.Literals: d501 :: SNat 501
- Clash.Promoted.Nat.Literals: d502 :: SNat 502
- Clash.Promoted.Nat.Literals: d503 :: SNat 503
- Clash.Promoted.Nat.Literals: d504 :: SNat 504
- Clash.Promoted.Nat.Literals: d505 :: SNat 505
- Clash.Promoted.Nat.Literals: d506 :: SNat 506
- Clash.Promoted.Nat.Literals: d507 :: SNat 507
- Clash.Promoted.Nat.Literals: d508 :: SNat 508
- Clash.Promoted.Nat.Literals: d509 :: SNat 509
- Clash.Promoted.Nat.Literals: d51 :: SNat 51
- Clash.Promoted.Nat.Literals: d510 :: SNat 510
- Clash.Promoted.Nat.Literals: d511 :: SNat 511
- Clash.Promoted.Nat.Literals: d512 :: SNat 512
- Clash.Promoted.Nat.Literals: d513 :: SNat 513
- Clash.Promoted.Nat.Literals: d514 :: SNat 514
- Clash.Promoted.Nat.Literals: d515 :: SNat 515
- Clash.Promoted.Nat.Literals: d516 :: SNat 516
- Clash.Promoted.Nat.Literals: d517 :: SNat 517
- Clash.Promoted.Nat.Literals: d518 :: SNat 518
- Clash.Promoted.Nat.Literals: d519 :: SNat 519
- Clash.Promoted.Nat.Literals: d52 :: SNat 52
- Clash.Promoted.Nat.Literals: d520 :: SNat 520
- Clash.Promoted.Nat.Literals: d521 :: SNat 521
- Clash.Promoted.Nat.Literals: d522 :: SNat 522
- Clash.Promoted.Nat.Literals: d523 :: SNat 523
- Clash.Promoted.Nat.Literals: d524 :: SNat 524
- Clash.Promoted.Nat.Literals: d525 :: SNat 525
- Clash.Promoted.Nat.Literals: d526 :: SNat 526
- Clash.Promoted.Nat.Literals: d527 :: SNat 527
- Clash.Promoted.Nat.Literals: d528 :: SNat 528
- Clash.Promoted.Nat.Literals: d529 :: SNat 529
- Clash.Promoted.Nat.Literals: d53 :: SNat 53
- Clash.Promoted.Nat.Literals: d530 :: SNat 530
- Clash.Promoted.Nat.Literals: d531 :: SNat 531
- Clash.Promoted.Nat.Literals: d532 :: SNat 532
- Clash.Promoted.Nat.Literals: d533 :: SNat 533
- Clash.Promoted.Nat.Literals: d534 :: SNat 534
- Clash.Promoted.Nat.Literals: d535 :: SNat 535
- Clash.Promoted.Nat.Literals: d536 :: SNat 536
- Clash.Promoted.Nat.Literals: d537 :: SNat 537
- Clash.Promoted.Nat.Literals: d538 :: SNat 538
- Clash.Promoted.Nat.Literals: d539 :: SNat 539
- Clash.Promoted.Nat.Literals: d54 :: SNat 54
- Clash.Promoted.Nat.Literals: d540 :: SNat 540
- Clash.Promoted.Nat.Literals: d541 :: SNat 541
- Clash.Promoted.Nat.Literals: d542 :: SNat 542
- Clash.Promoted.Nat.Literals: d543 :: SNat 543
- Clash.Promoted.Nat.Literals: d544 :: SNat 544
- Clash.Promoted.Nat.Literals: d545 :: SNat 545
- Clash.Promoted.Nat.Literals: d546 :: SNat 546
- Clash.Promoted.Nat.Literals: d547 :: SNat 547
- Clash.Promoted.Nat.Literals: d548 :: SNat 548
- Clash.Promoted.Nat.Literals: d549 :: SNat 549
- Clash.Promoted.Nat.Literals: d55 :: SNat 55
- Clash.Promoted.Nat.Literals: d550 :: SNat 550
- Clash.Promoted.Nat.Literals: d551 :: SNat 551
- Clash.Promoted.Nat.Literals: d552 :: SNat 552
- Clash.Promoted.Nat.Literals: d553 :: SNat 553
- Clash.Promoted.Nat.Literals: d554 :: SNat 554
- Clash.Promoted.Nat.Literals: d555 :: SNat 555
- Clash.Promoted.Nat.Literals: d556 :: SNat 556
- Clash.Promoted.Nat.Literals: d557 :: SNat 557
- Clash.Promoted.Nat.Literals: d558 :: SNat 558
- Clash.Promoted.Nat.Literals: d559 :: SNat 559
- Clash.Promoted.Nat.Literals: d56 :: SNat 56
- Clash.Promoted.Nat.Literals: d560 :: SNat 560
- Clash.Promoted.Nat.Literals: d561 :: SNat 561
- Clash.Promoted.Nat.Literals: d562 :: SNat 562
- Clash.Promoted.Nat.Literals: d563 :: SNat 563
- Clash.Promoted.Nat.Literals: d564 :: SNat 564
- Clash.Promoted.Nat.Literals: d565 :: SNat 565
- Clash.Promoted.Nat.Literals: d566 :: SNat 566
- Clash.Promoted.Nat.Literals: d567 :: SNat 567
- Clash.Promoted.Nat.Literals: d568 :: SNat 568
- Clash.Promoted.Nat.Literals: d569 :: SNat 569
- Clash.Promoted.Nat.Literals: d57 :: SNat 57
- Clash.Promoted.Nat.Literals: d570 :: SNat 570
- Clash.Promoted.Nat.Literals: d571 :: SNat 571
- Clash.Promoted.Nat.Literals: d572 :: SNat 572
- Clash.Promoted.Nat.Literals: d573 :: SNat 573
- Clash.Promoted.Nat.Literals: d574 :: SNat 574
- Clash.Promoted.Nat.Literals: d575 :: SNat 575
- Clash.Promoted.Nat.Literals: d576 :: SNat 576
- Clash.Promoted.Nat.Literals: d577 :: SNat 577
- Clash.Promoted.Nat.Literals: d578 :: SNat 578
- Clash.Promoted.Nat.Literals: d579 :: SNat 579
- Clash.Promoted.Nat.Literals: d58 :: SNat 58
- Clash.Promoted.Nat.Literals: d580 :: SNat 580
- Clash.Promoted.Nat.Literals: d581 :: SNat 581
- Clash.Promoted.Nat.Literals: d582 :: SNat 582
- Clash.Promoted.Nat.Literals: d583 :: SNat 583
- Clash.Promoted.Nat.Literals: d584 :: SNat 584
- Clash.Promoted.Nat.Literals: d585 :: SNat 585
- Clash.Promoted.Nat.Literals: d586 :: SNat 586
- Clash.Promoted.Nat.Literals: d587 :: SNat 587
- Clash.Promoted.Nat.Literals: d588 :: SNat 588
- Clash.Promoted.Nat.Literals: d589 :: SNat 589
- Clash.Promoted.Nat.Literals: d59 :: SNat 59
- Clash.Promoted.Nat.Literals: d590 :: SNat 590
- Clash.Promoted.Nat.Literals: d591 :: SNat 591
- Clash.Promoted.Nat.Literals: d592 :: SNat 592
- Clash.Promoted.Nat.Literals: d593 :: SNat 593
- Clash.Promoted.Nat.Literals: d594 :: SNat 594
- Clash.Promoted.Nat.Literals: d595 :: SNat 595
- Clash.Promoted.Nat.Literals: d596 :: SNat 596
- Clash.Promoted.Nat.Literals: d597 :: SNat 597
- Clash.Promoted.Nat.Literals: d598 :: SNat 598
- Clash.Promoted.Nat.Literals: d599 :: SNat 599
- Clash.Promoted.Nat.Literals: d6 :: SNat 6
- Clash.Promoted.Nat.Literals: d60 :: SNat 60
- Clash.Promoted.Nat.Literals: d600 :: SNat 600
- Clash.Promoted.Nat.Literals: d601 :: SNat 601
- Clash.Promoted.Nat.Literals: d602 :: SNat 602
- Clash.Promoted.Nat.Literals: d603 :: SNat 603
- Clash.Promoted.Nat.Literals: d604 :: SNat 604
- Clash.Promoted.Nat.Literals: d605 :: SNat 605
- Clash.Promoted.Nat.Literals: d606 :: SNat 606
- Clash.Promoted.Nat.Literals: d607 :: SNat 607
- Clash.Promoted.Nat.Literals: d608 :: SNat 608
- Clash.Promoted.Nat.Literals: d609 :: SNat 609
- Clash.Promoted.Nat.Literals: d61 :: SNat 61
- Clash.Promoted.Nat.Literals: d610 :: SNat 610
- Clash.Promoted.Nat.Literals: d611 :: SNat 611
- Clash.Promoted.Nat.Literals: d612 :: SNat 612
- Clash.Promoted.Nat.Literals: d613 :: SNat 613
- Clash.Promoted.Nat.Literals: d614 :: SNat 614
- Clash.Promoted.Nat.Literals: d615 :: SNat 615
- Clash.Promoted.Nat.Literals: d616 :: SNat 616
- Clash.Promoted.Nat.Literals: d617 :: SNat 617
- Clash.Promoted.Nat.Literals: d618 :: SNat 618
- Clash.Promoted.Nat.Literals: d619 :: SNat 619
- Clash.Promoted.Nat.Literals: d62 :: SNat 62
- Clash.Promoted.Nat.Literals: d620 :: SNat 620
- Clash.Promoted.Nat.Literals: d621 :: SNat 621
- Clash.Promoted.Nat.Literals: d622 :: SNat 622
- Clash.Promoted.Nat.Literals: d623 :: SNat 623
- Clash.Promoted.Nat.Literals: d624 :: SNat 624
- Clash.Promoted.Nat.Literals: d625 :: SNat 625
- Clash.Promoted.Nat.Literals: d626 :: SNat 626
- Clash.Promoted.Nat.Literals: d627 :: SNat 627
- Clash.Promoted.Nat.Literals: d628 :: SNat 628
- Clash.Promoted.Nat.Literals: d629 :: SNat 629
- Clash.Promoted.Nat.Literals: d63 :: SNat 63
- Clash.Promoted.Nat.Literals: d630 :: SNat 630
- Clash.Promoted.Nat.Literals: d631 :: SNat 631
- Clash.Promoted.Nat.Literals: d632 :: SNat 632
- Clash.Promoted.Nat.Literals: d633 :: SNat 633
- Clash.Promoted.Nat.Literals: d634 :: SNat 634
- Clash.Promoted.Nat.Literals: d635 :: SNat 635
- Clash.Promoted.Nat.Literals: d636 :: SNat 636
- Clash.Promoted.Nat.Literals: d637 :: SNat 637
- Clash.Promoted.Nat.Literals: d638 :: SNat 638
- Clash.Promoted.Nat.Literals: d639 :: SNat 639
- Clash.Promoted.Nat.Literals: d64 :: SNat 64
- Clash.Promoted.Nat.Literals: d640 :: SNat 640
- Clash.Promoted.Nat.Literals: d641 :: SNat 641
- Clash.Promoted.Nat.Literals: d642 :: SNat 642
- Clash.Promoted.Nat.Literals: d643 :: SNat 643
- Clash.Promoted.Nat.Literals: d644 :: SNat 644
- Clash.Promoted.Nat.Literals: d645 :: SNat 645
- Clash.Promoted.Nat.Literals: d646 :: SNat 646
- Clash.Promoted.Nat.Literals: d647 :: SNat 647
- Clash.Promoted.Nat.Literals: d648 :: SNat 648
- Clash.Promoted.Nat.Literals: d649 :: SNat 649
- Clash.Promoted.Nat.Literals: d65 :: SNat 65
- Clash.Promoted.Nat.Literals: d650 :: SNat 650
- Clash.Promoted.Nat.Literals: d651 :: SNat 651
- Clash.Promoted.Nat.Literals: d652 :: SNat 652
- Clash.Promoted.Nat.Literals: d653 :: SNat 653
- Clash.Promoted.Nat.Literals: d654 :: SNat 654
- Clash.Promoted.Nat.Literals: d655 :: SNat 655
- Clash.Promoted.Nat.Literals: d656 :: SNat 656
- Clash.Promoted.Nat.Literals: d657 :: SNat 657
- Clash.Promoted.Nat.Literals: d658 :: SNat 658
- Clash.Promoted.Nat.Literals: d659 :: SNat 659
- Clash.Promoted.Nat.Literals: d66 :: SNat 66
- Clash.Promoted.Nat.Literals: d660 :: SNat 660
- Clash.Promoted.Nat.Literals: d661 :: SNat 661
- Clash.Promoted.Nat.Literals: d662 :: SNat 662
- Clash.Promoted.Nat.Literals: d663 :: SNat 663
- Clash.Promoted.Nat.Literals: d664 :: SNat 664
- Clash.Promoted.Nat.Literals: d665 :: SNat 665
- Clash.Promoted.Nat.Literals: d666 :: SNat 666
- Clash.Promoted.Nat.Literals: d667 :: SNat 667
- Clash.Promoted.Nat.Literals: d668 :: SNat 668
- Clash.Promoted.Nat.Literals: d669 :: SNat 669
- Clash.Promoted.Nat.Literals: d67 :: SNat 67
- Clash.Promoted.Nat.Literals: d670 :: SNat 670
- Clash.Promoted.Nat.Literals: d671 :: SNat 671
- Clash.Promoted.Nat.Literals: d672 :: SNat 672
- Clash.Promoted.Nat.Literals: d673 :: SNat 673
- Clash.Promoted.Nat.Literals: d674 :: SNat 674
- Clash.Promoted.Nat.Literals: d675 :: SNat 675
- Clash.Promoted.Nat.Literals: d676 :: SNat 676
- Clash.Promoted.Nat.Literals: d677 :: SNat 677
- Clash.Promoted.Nat.Literals: d678 :: SNat 678
- Clash.Promoted.Nat.Literals: d679 :: SNat 679
- Clash.Promoted.Nat.Literals: d68 :: SNat 68
- Clash.Promoted.Nat.Literals: d680 :: SNat 680
- Clash.Promoted.Nat.Literals: d681 :: SNat 681
- Clash.Promoted.Nat.Literals: d682 :: SNat 682
- Clash.Promoted.Nat.Literals: d683 :: SNat 683
- Clash.Promoted.Nat.Literals: d684 :: SNat 684
- Clash.Promoted.Nat.Literals: d685 :: SNat 685
- Clash.Promoted.Nat.Literals: d686 :: SNat 686
- Clash.Promoted.Nat.Literals: d687 :: SNat 687
- Clash.Promoted.Nat.Literals: d688 :: SNat 688
- Clash.Promoted.Nat.Literals: d689 :: SNat 689
- Clash.Promoted.Nat.Literals: d69 :: SNat 69
- Clash.Promoted.Nat.Literals: d690 :: SNat 690
- Clash.Promoted.Nat.Literals: d691 :: SNat 691
- Clash.Promoted.Nat.Literals: d692 :: SNat 692
- Clash.Promoted.Nat.Literals: d693 :: SNat 693
- Clash.Promoted.Nat.Literals: d694 :: SNat 694
- Clash.Promoted.Nat.Literals: d695 :: SNat 695
- Clash.Promoted.Nat.Literals: d696 :: SNat 696
- Clash.Promoted.Nat.Literals: d697 :: SNat 697
- Clash.Promoted.Nat.Literals: d698 :: SNat 698
- Clash.Promoted.Nat.Literals: d699 :: SNat 699
- Clash.Promoted.Nat.Literals: d7 :: SNat 7
- Clash.Promoted.Nat.Literals: d70 :: SNat 70
- Clash.Promoted.Nat.Literals: d700 :: SNat 700
- Clash.Promoted.Nat.Literals: d701 :: SNat 701
- Clash.Promoted.Nat.Literals: d702 :: SNat 702
- Clash.Promoted.Nat.Literals: d703 :: SNat 703
- Clash.Promoted.Nat.Literals: d704 :: SNat 704
- Clash.Promoted.Nat.Literals: d705 :: SNat 705
- Clash.Promoted.Nat.Literals: d706 :: SNat 706
- Clash.Promoted.Nat.Literals: d707 :: SNat 707
- Clash.Promoted.Nat.Literals: d708 :: SNat 708
- Clash.Promoted.Nat.Literals: d709 :: SNat 709
- Clash.Promoted.Nat.Literals: d71 :: SNat 71
- Clash.Promoted.Nat.Literals: d710 :: SNat 710
- Clash.Promoted.Nat.Literals: d711 :: SNat 711
- Clash.Promoted.Nat.Literals: d712 :: SNat 712
- Clash.Promoted.Nat.Literals: d713 :: SNat 713
- Clash.Promoted.Nat.Literals: d714 :: SNat 714
- Clash.Promoted.Nat.Literals: d715 :: SNat 715
- Clash.Promoted.Nat.Literals: d716 :: SNat 716
- Clash.Promoted.Nat.Literals: d717 :: SNat 717
- Clash.Promoted.Nat.Literals: d718 :: SNat 718
- Clash.Promoted.Nat.Literals: d719 :: SNat 719
- Clash.Promoted.Nat.Literals: d72 :: SNat 72
- Clash.Promoted.Nat.Literals: d720 :: SNat 720
- Clash.Promoted.Nat.Literals: d721 :: SNat 721
- Clash.Promoted.Nat.Literals: d722 :: SNat 722
- Clash.Promoted.Nat.Literals: d723 :: SNat 723
- Clash.Promoted.Nat.Literals: d724 :: SNat 724
- Clash.Promoted.Nat.Literals: d725 :: SNat 725
- Clash.Promoted.Nat.Literals: d726 :: SNat 726
- Clash.Promoted.Nat.Literals: d727 :: SNat 727
- Clash.Promoted.Nat.Literals: d728 :: SNat 728
- Clash.Promoted.Nat.Literals: d729 :: SNat 729
- Clash.Promoted.Nat.Literals: d73 :: SNat 73
- Clash.Promoted.Nat.Literals: d730 :: SNat 730
- Clash.Promoted.Nat.Literals: d731 :: SNat 731
- Clash.Promoted.Nat.Literals: d732 :: SNat 732
- Clash.Promoted.Nat.Literals: d733 :: SNat 733
- Clash.Promoted.Nat.Literals: d734 :: SNat 734
- Clash.Promoted.Nat.Literals: d735 :: SNat 735
- Clash.Promoted.Nat.Literals: d736 :: SNat 736
- Clash.Promoted.Nat.Literals: d737 :: SNat 737
- Clash.Promoted.Nat.Literals: d738 :: SNat 738
- Clash.Promoted.Nat.Literals: d739 :: SNat 739
- Clash.Promoted.Nat.Literals: d74 :: SNat 74
- Clash.Promoted.Nat.Literals: d740 :: SNat 740
- Clash.Promoted.Nat.Literals: d741 :: SNat 741
- Clash.Promoted.Nat.Literals: d742 :: SNat 742
- Clash.Promoted.Nat.Literals: d743 :: SNat 743
- Clash.Promoted.Nat.Literals: d744 :: SNat 744
- Clash.Promoted.Nat.Literals: d745 :: SNat 745
- Clash.Promoted.Nat.Literals: d746 :: SNat 746
- Clash.Promoted.Nat.Literals: d747 :: SNat 747
- Clash.Promoted.Nat.Literals: d748 :: SNat 748
- Clash.Promoted.Nat.Literals: d749 :: SNat 749
- Clash.Promoted.Nat.Literals: d75 :: SNat 75
- Clash.Promoted.Nat.Literals: d750 :: SNat 750
- Clash.Promoted.Nat.Literals: d751 :: SNat 751
- Clash.Promoted.Nat.Literals: d752 :: SNat 752
- Clash.Promoted.Nat.Literals: d753 :: SNat 753
- Clash.Promoted.Nat.Literals: d754 :: SNat 754
- Clash.Promoted.Nat.Literals: d755 :: SNat 755
- Clash.Promoted.Nat.Literals: d756 :: SNat 756
- Clash.Promoted.Nat.Literals: d757 :: SNat 757
- Clash.Promoted.Nat.Literals: d758 :: SNat 758
- Clash.Promoted.Nat.Literals: d759 :: SNat 759
- Clash.Promoted.Nat.Literals: d76 :: SNat 76
- Clash.Promoted.Nat.Literals: d760 :: SNat 760
- Clash.Promoted.Nat.Literals: d761 :: SNat 761
- Clash.Promoted.Nat.Literals: d762 :: SNat 762
- Clash.Promoted.Nat.Literals: d763 :: SNat 763
- Clash.Promoted.Nat.Literals: d764 :: SNat 764
- Clash.Promoted.Nat.Literals: d765 :: SNat 765
- Clash.Promoted.Nat.Literals: d766 :: SNat 766
- Clash.Promoted.Nat.Literals: d767 :: SNat 767
- Clash.Promoted.Nat.Literals: d768 :: SNat 768
- Clash.Promoted.Nat.Literals: d769 :: SNat 769
- Clash.Promoted.Nat.Literals: d77 :: SNat 77
- Clash.Promoted.Nat.Literals: d770 :: SNat 770
- Clash.Promoted.Nat.Literals: d771 :: SNat 771
- Clash.Promoted.Nat.Literals: d772 :: SNat 772
- Clash.Promoted.Nat.Literals: d773 :: SNat 773
- Clash.Promoted.Nat.Literals: d774 :: SNat 774
- Clash.Promoted.Nat.Literals: d775 :: SNat 775
- Clash.Promoted.Nat.Literals: d776 :: SNat 776
- Clash.Promoted.Nat.Literals: d777 :: SNat 777
- Clash.Promoted.Nat.Literals: d778 :: SNat 778
- Clash.Promoted.Nat.Literals: d779 :: SNat 779
- Clash.Promoted.Nat.Literals: d78 :: SNat 78
- Clash.Promoted.Nat.Literals: d780 :: SNat 780
- Clash.Promoted.Nat.Literals: d781 :: SNat 781
- Clash.Promoted.Nat.Literals: d782 :: SNat 782
- Clash.Promoted.Nat.Literals: d783 :: SNat 783
- Clash.Promoted.Nat.Literals: d784 :: SNat 784
- Clash.Promoted.Nat.Literals: d785 :: SNat 785
- Clash.Promoted.Nat.Literals: d786 :: SNat 786
- Clash.Promoted.Nat.Literals: d787 :: SNat 787
- Clash.Promoted.Nat.Literals: d788 :: SNat 788
- Clash.Promoted.Nat.Literals: d789 :: SNat 789
- Clash.Promoted.Nat.Literals: d79 :: SNat 79
- Clash.Promoted.Nat.Literals: d790 :: SNat 790
- Clash.Promoted.Nat.Literals: d791 :: SNat 791
- Clash.Promoted.Nat.Literals: d792 :: SNat 792
- Clash.Promoted.Nat.Literals: d793 :: SNat 793
- Clash.Promoted.Nat.Literals: d794 :: SNat 794
- Clash.Promoted.Nat.Literals: d795 :: SNat 795
- Clash.Promoted.Nat.Literals: d796 :: SNat 796
- Clash.Promoted.Nat.Literals: d797 :: SNat 797
- Clash.Promoted.Nat.Literals: d798 :: SNat 798
- Clash.Promoted.Nat.Literals: d799 :: SNat 799
- Clash.Promoted.Nat.Literals: d8 :: SNat 8
- Clash.Promoted.Nat.Literals: d80 :: SNat 80
- Clash.Promoted.Nat.Literals: d800 :: SNat 800
- Clash.Promoted.Nat.Literals: d801 :: SNat 801
- Clash.Promoted.Nat.Literals: d802 :: SNat 802
- Clash.Promoted.Nat.Literals: d803 :: SNat 803
- Clash.Promoted.Nat.Literals: d804 :: SNat 804
- Clash.Promoted.Nat.Literals: d805 :: SNat 805
- Clash.Promoted.Nat.Literals: d806 :: SNat 806
- Clash.Promoted.Nat.Literals: d807 :: SNat 807
- Clash.Promoted.Nat.Literals: d808 :: SNat 808
- Clash.Promoted.Nat.Literals: d809 :: SNat 809
- Clash.Promoted.Nat.Literals: d81 :: SNat 81
- Clash.Promoted.Nat.Literals: d810 :: SNat 810
- Clash.Promoted.Nat.Literals: d811 :: SNat 811
- Clash.Promoted.Nat.Literals: d812 :: SNat 812
- Clash.Promoted.Nat.Literals: d813 :: SNat 813
- Clash.Promoted.Nat.Literals: d814 :: SNat 814
- Clash.Promoted.Nat.Literals: d815 :: SNat 815
- Clash.Promoted.Nat.Literals: d816 :: SNat 816
- Clash.Promoted.Nat.Literals: d817 :: SNat 817
- Clash.Promoted.Nat.Literals: d818 :: SNat 818
- Clash.Promoted.Nat.Literals: d819 :: SNat 819
- Clash.Promoted.Nat.Literals: d82 :: SNat 82
- Clash.Promoted.Nat.Literals: d820 :: SNat 820
- Clash.Promoted.Nat.Literals: d821 :: SNat 821
- Clash.Promoted.Nat.Literals: d822 :: SNat 822
- Clash.Promoted.Nat.Literals: d823 :: SNat 823
- Clash.Promoted.Nat.Literals: d824 :: SNat 824
- Clash.Promoted.Nat.Literals: d825 :: SNat 825
- Clash.Promoted.Nat.Literals: d826 :: SNat 826
- Clash.Promoted.Nat.Literals: d827 :: SNat 827
- Clash.Promoted.Nat.Literals: d828 :: SNat 828
- Clash.Promoted.Nat.Literals: d829 :: SNat 829
- Clash.Promoted.Nat.Literals: d83 :: SNat 83
- Clash.Promoted.Nat.Literals: d830 :: SNat 830
- Clash.Promoted.Nat.Literals: d831 :: SNat 831
- Clash.Promoted.Nat.Literals: d832 :: SNat 832
- Clash.Promoted.Nat.Literals: d833 :: SNat 833
- Clash.Promoted.Nat.Literals: d834 :: SNat 834
- Clash.Promoted.Nat.Literals: d835 :: SNat 835
- Clash.Promoted.Nat.Literals: d836 :: SNat 836
- Clash.Promoted.Nat.Literals: d837 :: SNat 837
- Clash.Promoted.Nat.Literals: d838 :: SNat 838
- Clash.Promoted.Nat.Literals: d839 :: SNat 839
- Clash.Promoted.Nat.Literals: d84 :: SNat 84
- Clash.Promoted.Nat.Literals: d840 :: SNat 840
- Clash.Promoted.Nat.Literals: d841 :: SNat 841
- Clash.Promoted.Nat.Literals: d842 :: SNat 842
- Clash.Promoted.Nat.Literals: d843 :: SNat 843
- Clash.Promoted.Nat.Literals: d844 :: SNat 844
- Clash.Promoted.Nat.Literals: d845 :: SNat 845
- Clash.Promoted.Nat.Literals: d846 :: SNat 846
- Clash.Promoted.Nat.Literals: d847 :: SNat 847
- Clash.Promoted.Nat.Literals: d848 :: SNat 848
- Clash.Promoted.Nat.Literals: d849 :: SNat 849
- Clash.Promoted.Nat.Literals: d85 :: SNat 85
- Clash.Promoted.Nat.Literals: d850 :: SNat 850
- Clash.Promoted.Nat.Literals: d851 :: SNat 851
- Clash.Promoted.Nat.Literals: d852 :: SNat 852
- Clash.Promoted.Nat.Literals: d853 :: SNat 853
- Clash.Promoted.Nat.Literals: d854 :: SNat 854
- Clash.Promoted.Nat.Literals: d855 :: SNat 855
- Clash.Promoted.Nat.Literals: d856 :: SNat 856
- Clash.Promoted.Nat.Literals: d857 :: SNat 857
- Clash.Promoted.Nat.Literals: d858 :: SNat 858
- Clash.Promoted.Nat.Literals: d859 :: SNat 859
- Clash.Promoted.Nat.Literals: d86 :: SNat 86
- Clash.Promoted.Nat.Literals: d860 :: SNat 860
- Clash.Promoted.Nat.Literals: d861 :: SNat 861
- Clash.Promoted.Nat.Literals: d862 :: SNat 862
- Clash.Promoted.Nat.Literals: d863 :: SNat 863
- Clash.Promoted.Nat.Literals: d864 :: SNat 864
- Clash.Promoted.Nat.Literals: d865 :: SNat 865
- Clash.Promoted.Nat.Literals: d866 :: SNat 866
- Clash.Promoted.Nat.Literals: d867 :: SNat 867
- Clash.Promoted.Nat.Literals: d868 :: SNat 868
- Clash.Promoted.Nat.Literals: d869 :: SNat 869
- Clash.Promoted.Nat.Literals: d87 :: SNat 87
- Clash.Promoted.Nat.Literals: d870 :: SNat 870
- Clash.Promoted.Nat.Literals: d871 :: SNat 871
- Clash.Promoted.Nat.Literals: d872 :: SNat 872
- Clash.Promoted.Nat.Literals: d873 :: SNat 873
- Clash.Promoted.Nat.Literals: d874 :: SNat 874
- Clash.Promoted.Nat.Literals: d875 :: SNat 875
- Clash.Promoted.Nat.Literals: d876 :: SNat 876
- Clash.Promoted.Nat.Literals: d877 :: SNat 877
- Clash.Promoted.Nat.Literals: d878 :: SNat 878
- Clash.Promoted.Nat.Literals: d879 :: SNat 879
- Clash.Promoted.Nat.Literals: d88 :: SNat 88
- Clash.Promoted.Nat.Literals: d880 :: SNat 880
- Clash.Promoted.Nat.Literals: d881 :: SNat 881
- Clash.Promoted.Nat.Literals: d882 :: SNat 882
- Clash.Promoted.Nat.Literals: d883 :: SNat 883
- Clash.Promoted.Nat.Literals: d884 :: SNat 884
- Clash.Promoted.Nat.Literals: d885 :: SNat 885
- Clash.Promoted.Nat.Literals: d886 :: SNat 886
- Clash.Promoted.Nat.Literals: d887 :: SNat 887
- Clash.Promoted.Nat.Literals: d888 :: SNat 888
- Clash.Promoted.Nat.Literals: d889 :: SNat 889
- Clash.Promoted.Nat.Literals: d89 :: SNat 89
- Clash.Promoted.Nat.Literals: d890 :: SNat 890
- Clash.Promoted.Nat.Literals: d891 :: SNat 891
- Clash.Promoted.Nat.Literals: d892 :: SNat 892
- Clash.Promoted.Nat.Literals: d893 :: SNat 893
- Clash.Promoted.Nat.Literals: d894 :: SNat 894
- Clash.Promoted.Nat.Literals: d895 :: SNat 895
- Clash.Promoted.Nat.Literals: d896 :: SNat 896
- Clash.Promoted.Nat.Literals: d897 :: SNat 897
- Clash.Promoted.Nat.Literals: d898 :: SNat 898
- Clash.Promoted.Nat.Literals: d899 :: SNat 899
- Clash.Promoted.Nat.Literals: d9 :: SNat 9
- Clash.Promoted.Nat.Literals: d90 :: SNat 90
- Clash.Promoted.Nat.Literals: d900 :: SNat 900
- Clash.Promoted.Nat.Literals: d901 :: SNat 901
- Clash.Promoted.Nat.Literals: d902 :: SNat 902
- Clash.Promoted.Nat.Literals: d903 :: SNat 903
- Clash.Promoted.Nat.Literals: d904 :: SNat 904
- Clash.Promoted.Nat.Literals: d905 :: SNat 905
- Clash.Promoted.Nat.Literals: d906 :: SNat 906
- Clash.Promoted.Nat.Literals: d907 :: SNat 907
- Clash.Promoted.Nat.Literals: d908 :: SNat 908
- Clash.Promoted.Nat.Literals: d909 :: SNat 909
- Clash.Promoted.Nat.Literals: d91 :: SNat 91
- Clash.Promoted.Nat.Literals: d910 :: SNat 910
- Clash.Promoted.Nat.Literals: d911 :: SNat 911
- Clash.Promoted.Nat.Literals: d912 :: SNat 912
- Clash.Promoted.Nat.Literals: d913 :: SNat 913
- Clash.Promoted.Nat.Literals: d914 :: SNat 914
- Clash.Promoted.Nat.Literals: d915 :: SNat 915
- Clash.Promoted.Nat.Literals: d916 :: SNat 916
- Clash.Promoted.Nat.Literals: d917 :: SNat 917
- Clash.Promoted.Nat.Literals: d918 :: SNat 918
- Clash.Promoted.Nat.Literals: d919 :: SNat 919
- Clash.Promoted.Nat.Literals: d92 :: SNat 92
- Clash.Promoted.Nat.Literals: d920 :: SNat 920
- Clash.Promoted.Nat.Literals: d921 :: SNat 921
- Clash.Promoted.Nat.Literals: d922 :: SNat 922
- Clash.Promoted.Nat.Literals: d923 :: SNat 923
- Clash.Promoted.Nat.Literals: d924 :: SNat 924
- Clash.Promoted.Nat.Literals: d925 :: SNat 925
- Clash.Promoted.Nat.Literals: d926 :: SNat 926
- Clash.Promoted.Nat.Literals: d927 :: SNat 927
- Clash.Promoted.Nat.Literals: d928 :: SNat 928
- Clash.Promoted.Nat.Literals: d929 :: SNat 929
- Clash.Promoted.Nat.Literals: d93 :: SNat 93
- Clash.Promoted.Nat.Literals: d930 :: SNat 930
- Clash.Promoted.Nat.Literals: d931 :: SNat 931
- Clash.Promoted.Nat.Literals: d932 :: SNat 932
- Clash.Promoted.Nat.Literals: d933 :: SNat 933
- Clash.Promoted.Nat.Literals: d934 :: SNat 934
- Clash.Promoted.Nat.Literals: d935 :: SNat 935
- Clash.Promoted.Nat.Literals: d936 :: SNat 936
- Clash.Promoted.Nat.Literals: d937 :: SNat 937
- Clash.Promoted.Nat.Literals: d938 :: SNat 938
- Clash.Promoted.Nat.Literals: d939 :: SNat 939
- Clash.Promoted.Nat.Literals: d94 :: SNat 94
- Clash.Promoted.Nat.Literals: d940 :: SNat 940
- Clash.Promoted.Nat.Literals: d941 :: SNat 941
- Clash.Promoted.Nat.Literals: d942 :: SNat 942
- Clash.Promoted.Nat.Literals: d943 :: SNat 943
- Clash.Promoted.Nat.Literals: d944 :: SNat 944
- Clash.Promoted.Nat.Literals: d945 :: SNat 945
- Clash.Promoted.Nat.Literals: d946 :: SNat 946
- Clash.Promoted.Nat.Literals: d947 :: SNat 947
- Clash.Promoted.Nat.Literals: d948 :: SNat 948
- Clash.Promoted.Nat.Literals: d949 :: SNat 949
- Clash.Promoted.Nat.Literals: d95 :: SNat 95
- Clash.Promoted.Nat.Literals: d950 :: SNat 950
- Clash.Promoted.Nat.Literals: d951 :: SNat 951
- Clash.Promoted.Nat.Literals: d952 :: SNat 952
- Clash.Promoted.Nat.Literals: d953 :: SNat 953
- Clash.Promoted.Nat.Literals: d954 :: SNat 954
- Clash.Promoted.Nat.Literals: d955 :: SNat 955
- Clash.Promoted.Nat.Literals: d956 :: SNat 956
- Clash.Promoted.Nat.Literals: d957 :: SNat 957
- Clash.Promoted.Nat.Literals: d958 :: SNat 958
- Clash.Promoted.Nat.Literals: d959 :: SNat 959
- Clash.Promoted.Nat.Literals: d96 :: SNat 96
- Clash.Promoted.Nat.Literals: d960 :: SNat 960
- Clash.Promoted.Nat.Literals: d961 :: SNat 961
- Clash.Promoted.Nat.Literals: d962 :: SNat 962
- Clash.Promoted.Nat.Literals: d963 :: SNat 963
- Clash.Promoted.Nat.Literals: d964 :: SNat 964
- Clash.Promoted.Nat.Literals: d965 :: SNat 965
- Clash.Promoted.Nat.Literals: d966 :: SNat 966
- Clash.Promoted.Nat.Literals: d967 :: SNat 967
- Clash.Promoted.Nat.Literals: d968 :: SNat 968
- Clash.Promoted.Nat.Literals: d969 :: SNat 969
- Clash.Promoted.Nat.Literals: d97 :: SNat 97
- Clash.Promoted.Nat.Literals: d970 :: SNat 970
- Clash.Promoted.Nat.Literals: d971 :: SNat 971
- Clash.Promoted.Nat.Literals: d972 :: SNat 972
- Clash.Promoted.Nat.Literals: d973 :: SNat 973
- Clash.Promoted.Nat.Literals: d974 :: SNat 974
- Clash.Promoted.Nat.Literals: d975 :: SNat 975
- Clash.Promoted.Nat.Literals: d976 :: SNat 976
- Clash.Promoted.Nat.Literals: d977 :: SNat 977
- Clash.Promoted.Nat.Literals: d978 :: SNat 978
- Clash.Promoted.Nat.Literals: d979 :: SNat 979
- Clash.Promoted.Nat.Literals: d98 :: SNat 98
- Clash.Promoted.Nat.Literals: d980 :: SNat 980
- Clash.Promoted.Nat.Literals: d981 :: SNat 981
- Clash.Promoted.Nat.Literals: d982 :: SNat 982
- Clash.Promoted.Nat.Literals: d983 :: SNat 983
- Clash.Promoted.Nat.Literals: d984 :: SNat 984
- Clash.Promoted.Nat.Literals: d985 :: SNat 985
- Clash.Promoted.Nat.Literals: d986 :: SNat 986
- Clash.Promoted.Nat.Literals: d987 :: SNat 987
- Clash.Promoted.Nat.Literals: d988 :: SNat 988
- Clash.Promoted.Nat.Literals: d989 :: SNat 989
- Clash.Promoted.Nat.Literals: d99 :: SNat 99
- Clash.Promoted.Nat.Literals: d990 :: SNat 990
- Clash.Promoted.Nat.Literals: d991 :: SNat 991
- Clash.Promoted.Nat.Literals: d992 :: SNat 992
- Clash.Promoted.Nat.Literals: d993 :: SNat 993
- Clash.Promoted.Nat.Literals: d994 :: SNat 994
- Clash.Promoted.Nat.Literals: d995 :: SNat 995
- Clash.Promoted.Nat.Literals: d996 :: SNat 996
- Clash.Promoted.Nat.Literals: d997 :: SNat 997
- Clash.Promoted.Nat.Literals: d998 :: SNat 998
- Clash.Promoted.Nat.Literals: d999 :: SNat 999
- Clash.Signal: Dom :: Symbol -> Nat -> Domain
- Clash.Signal: Gated :: ClockKind
- Clash.Signal: Source :: ClockKind
- Clash.Signal: [clkPeriod] :: Domain -> Nat
- Clash.Signal: [domainName] :: Domain -> Symbol
- Clash.Signal: asyncResetGen :: Reset domain 'Asynchronous
- Clash.Signal: data ClockKind
- Clash.Signal: data Domain
- Clash.Signal: exposeClockReset :: (HiddenClockReset domain gated synchronous => r) -> (Clock domain gated -> Reset domain synchronous -> r)
- Clash.Signal: fromSyncReset :: Reset domain 'Synchronous -> Signal domain Bool
- Clash.Signal: hideClockReset :: HiddenClockReset domain gated synchronous => (Clock domain gated -> Reset domain synchronous -> r) -> r
- Clash.Signal: syncResetGen :: (domain ~ 'Dom n clkPeriod, KnownNat clkPeriod) => Reset domain 'Synchronous
- Clash.Signal: tbClockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Signal domain Bool -> Clock domain 'Source
- Clash.Signal: tbSystemClockGen :: Signal System Bool -> Clock System 'Source
- Clash.Signal: type HiddenClockReset domain gated synchronous = (HiddenClock domain gated, HiddenReset domain synchronous)
- Clash.Signal: type SystemClockReset = HiddenClockReset System 'Source 'Asynchronous
- Clash.Signal: unsafeFromAsyncReset :: Reset domain 'Asynchronous -> Signal domain Bool
- Clash.Signal: unsafeToAsyncReset :: Signal domain Bool -> Reset domain 'Asynchronous
- Clash.Signal: unsafeToSyncReset :: Signal domain Bool -> Reset domain 'Synchronous
- Clash.Signal: withClockReset :: Clock domain gated -> Reset domain synchronous -> (HiddenClockReset domain gated synchronous => r) -> r
- Clash.Signal.Bundle: instance Clash.Signal.Bundle.Bundle (GHC.Base.Maybe a)
- Clash.Signal.Internal: Dom :: Symbol -> Nat -> Domain
- Clash.Signal.Internal: Gated :: ClockKind
- Clash.Signal.Internal: Source :: ClockKind
- Clash.Signal.Internal: [Async] :: Signal domain Bool -> Reset domain 'Asynchronous
- Clash.Signal.Internal: [Clock] :: (domain ~ ( 'Dom name period)) => SSymbol name -> SNat period -> Clock domain 'Source
- Clash.Signal.Internal: [GatedClock] :: (domain ~ ( 'Dom name period)) => SSymbol name -> SNat period -> Signal domain Bool -> Clock domain 'Gated
- Clash.Signal.Internal: [Sync] :: Signal domain Bool -> Reset domain 'Synchronous
- Clash.Signal.Internal: [clkPeriod] :: Domain -> Nat
- Clash.Signal.Internal: [domainName] :: Domain -> Symbol
- Clash.Signal.Internal: asyncResetGen :: Reset domain 'Asynchronous
- Clash.Signal.Internal: clockEnable :: Clock domain gated -> Maybe (Signal domain Bool)
- Clash.Signal.Internal: clockGate :: Clock domain gated -> Signal domain Bool -> Clock domain 'Gated
- Clash.Signal.Internal: clockPeriod :: Num a => Clock domain gated -> a
- Clash.Signal.Internal: data ClockKind
- Clash.Signal.Internal: data Domain
- Clash.Signal.Internal: fromSyncReset :: Reset domain 'Synchronous -> Signal domain Bool
- Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.ClockKind
- Clash.Signal.Internal: instance Data.Default.Class.Default a => Data.Default.Class.Default (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance Data.Foldable.Foldable (Clash.Signal.Internal.Signal domain)
- Clash.Signal.Internal: instance Data.Traversable.Traversable (Clash.Signal.Internal.Signal domain)
- Clash.Signal.Internal: instance GHC.Base.Applicative (Clash.Signal.Internal.Signal domain)
- Clash.Signal.Internal: instance GHC.Base.Functor (Clash.Signal.Internal.Signal domain)
- Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.ClockKind
- Clash.Signal.Internal: instance GHC.Classes.Ord Clash.Signal.Internal.ClockKind
- Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.ClockKind
- Clash.Signal.Internal: instance GHC.Num.Num a => GHC.Num.Num (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance GHC.Real.Fractional a => GHC.Real.Fractional (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.Clock domain gated)
- Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.ClockKind
- Clash.Signal.Internal: instance GHC.Show.Show a => GHC.Show.Show (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance Language.Haskell.TH.Syntax.Lift a => Language.Haskell.TH.Syntax.Lift (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: instance Test.QuickCheck.Arbitrary.CoArbitrary a => Test.QuickCheck.Arbitrary.CoArbitrary (Clash.Signal.Internal.Signal domain a)
- Clash.Signal.Internal: syncResetGen :: (domain ~ 'Dom n clkPeriod, KnownNat clkPeriod) => Reset domain 'Synchronous
- Clash.Signal.Internal: tbClockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Signal domain Bool -> Clock domain 'Source
- Clash.Signal.Internal: unsafeFromAsyncReset :: Reset domain 'Asynchronous -> Signal domain Bool
- Clash.Signal.Internal: unsafeToAsyncReset :: Signal domain Bool -> Reset domain 'Asynchronous
- Clash.Signal.Internal: unsafeToSyncReset :: Signal domain Bool -> Reset domain 'Synchronous
- Clash.Sized.Fixed: instance (size ~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Enum.Bounded (rep size), GHC.Real.Integral (rep size)) => GHC.Read.Read (Clash.Sized.Fixed.Fixed rep int frac)
- Clash.Sized.Fixed: instance (size ~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Real.Integral (rep size)) => Clash.XException.ShowX (Clash.Sized.Fixed.Fixed rep int frac)
- Clash.Sized.Fixed: instance (size ~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Real.Integral (rep size)) => GHC.Show.Show (Clash.Sized.Fixed.Fixed rep int frac)
- Clash.Sized.Internal.BitVector: instance GHC.Classes.Eq (Clash.Sized.Internal.BitVector.BitVector n)
- Clash.Sized.Internal.BitVector: instance GHC.Classes.Ord (Clash.Sized.Internal.BitVector.BitVector n)
- Clash.Sized.Internal.BitVector: newtype Bit
- Clash.Sized.Internal.BitVector: newtype BitVector (n :: Nat)
- Clash.Sized.Internal.BitVector: resize# :: forall n m. KnownNat m => BitVector n -> BitVector m
- Clash.Sized.Internal.Index: instance GHC.TypeNats.KnownNat n => Clash.Class.BitPack.BitPack (Clash.Sized.Internal.Index.Index n)
- Clash.Sized.Internal.Unsigned: instance Clash.Class.BitPack.BitPack (Clash.Sized.Internal.Unsigned.Unsigned n)
- Clash.XException: data XException
- Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (GHC.Base.Maybe a)
- Clash.XException: instance GHC.Exception.Exception Clash.XException.XException
- Clash.XException: maybeX :: NFData a => a -> Maybe a
+ Clash.Annotations.BitRepresentation: ConstrRepr :: Name -> BitMask -> Value -> [FieldAnn] -> ConstrRepr
+ Clash.Annotations.BitRepresentation: DataReprAnn :: Type -> Size -> [ConstrRepr] -> DataReprAnn
+ Clash.Annotations.BitRepresentation: data ConstrRepr
+ Clash.Annotations.BitRepresentation: data DataReprAnn
+ Clash.Annotations.BitRepresentation: instance Data.Data.Data Clash.Annotations.BitRepresentation.ConstrRepr
+ Clash.Annotations.BitRepresentation: instance Data.Data.Data Clash.Annotations.BitRepresentation.DataReprAnn
+ Clash.Annotations.BitRepresentation: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.ConstrRepr
+ Clash.Annotations.BitRepresentation: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.DataReprAnn
+ Clash.Annotations.BitRepresentation: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.ConstrRepr
+ Clash.Annotations.BitRepresentation: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.DataReprAnn
+ Clash.Annotations.BitRepresentation: instance GHC.Show.Show Clash.Annotations.BitRepresentation.ConstrRepr
+ Clash.Annotations.BitRepresentation: instance GHC.Show.Show Clash.Annotations.BitRepresentation.DataReprAnn
+ Clash.Annotations.BitRepresentation: instance Language.Haskell.TH.Syntax.Lift Clash.Annotations.BitRepresentation.ConstrRepr
+ Clash.Annotations.BitRepresentation: instance Language.Haskell.TH.Syntax.Lift Clash.Annotations.BitRepresentation.DataReprAnn
+ Clash.Annotations.BitRepresentation: liftQ :: Lift a => Q a -> Q Exp
+ Clash.Annotations.BitRepresentation: type BitMask = Integer
+ Clash.Annotations.BitRepresentation: type FieldAnn = BitMask
+ Clash.Annotations.BitRepresentation: type Size = Int
+ Clash.Annotations.BitRepresentation: type Value = Integer
+ Clash.Annotations.BitRepresentation.Deriving: Binary :: ConstructorType
+ Clash.Annotations.BitRepresentation.Deriving: OneHot :: ConstructorType
+ Clash.Annotations.BitRepresentation.Deriving: OverlapL :: FieldsType
+ Clash.Annotations.BitRepresentation.Deriving: OverlapR :: FieldsType
+ Clash.Annotations.BitRepresentation.Deriving: Wide :: FieldsType
+ Clash.Annotations.BitRepresentation.Deriving: blueSpecDerivator :: Derivator
+ Clash.Annotations.BitRepresentation.Deriving: data ConstructorType
+ Clash.Annotations.BitRepresentation.Deriving: data FieldsType
+ Clash.Annotations.BitRepresentation.Deriving: defaultDerivator :: Derivator
+ Clash.Annotations.BitRepresentation.Deriving: deriveAnnotation :: Derivator -> Q Type -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: deriveBitPack :: Q Type -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: deriveBlueSpecAnnotation :: Q Type -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: deriveDefaultAnnotation :: Q Type -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: derivePackedAnnotation :: Q Type -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: derivePackedMaybeAnnotation :: DataReprAnn -> Q [Dec]
+ Clash.Annotations.BitRepresentation.Deriving: dontApplyInHDL :: (a -> b) -> a -> b
+ Clash.Annotations.BitRepresentation.Deriving: instance Control.DeepSeq.NFData Clash.Annotations.BitRepresentation.Deriving.Bit'
+ Clash.Annotations.BitRepresentation.Deriving: instance Data.Data.Data Clash.Annotations.BitRepresentation.Deriving.BitMaskOrigin
+ Clash.Annotations.BitRepresentation.Deriving: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.Deriving.Bit'
+ Clash.Annotations.BitRepresentation.Deriving: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.Deriving.Bit'
+ Clash.Annotations.BitRepresentation.Deriving: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Deriving.Bit'
+ Clash.Annotations.BitRepresentation.Deriving: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Deriving.BitMaskOrigin
+ Clash.Annotations.BitRepresentation.Deriving: instance Language.Haskell.TH.Syntax.Lift Clash.Annotations.BitRepresentation.Deriving.BitMaskOrigin
+ Clash.Annotations.BitRepresentation.Deriving: packedDerivator :: Derivator
+ Clash.Annotations.BitRepresentation.Deriving: packedMaybeDerivator :: DataReprAnn -> Derivator
+ Clash.Annotations.BitRepresentation.Deriving: simpleDerivator :: ConstructorType -> FieldsType -> Derivator
+ Clash.Annotations.BitRepresentation.Deriving: type DataReprAnnExp = Exp
+ Clash.Annotations.BitRepresentation.Deriving: type Derivator = Type -> Q DataReprAnnExp
+ Clash.Annotations.BitRepresentation.Internal: AppTy' :: Type' -> Type' -> Type'
+ Clash.Annotations.BitRepresentation.Internal: ConstTy' :: Text -> Type'
+ Clash.Annotations.BitRepresentation.Internal: ConstrRepr' :: Text -> Int -> BitMask -> Value -> [FieldAnn] -> ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: DataRepr' :: Type' -> Size -> [ConstrRepr'] -> DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: LitTy' :: Integer -> Type'
+ Clash.Annotations.BitRepresentation.Internal: buildCustomReprs :: [DataRepr'] -> CustomReprs
+ Clash.Annotations.BitRepresentation.Internal: constrReprToConstrRepr' :: Int -> ConstrRepr -> ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: data ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: data DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: data Type'
+ Clash.Annotations.BitRepresentation.Internal: dataReprAnnToDataRepr' :: DataReprAnn -> DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: getConstrRepr :: Text -> CustomReprs -> Maybe ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: getDataRepr :: Type' -> CustomReprs -> Maybe DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance Control.DeepSeq.NFData Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance Control.DeepSeq.NFData Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance Control.DeepSeq.NFData Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: instance Data.Hashable.Class.Hashable Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance Data.Hashable.Class.Hashable Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance Data.Hashable.Class.Hashable Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Ord Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Ord Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Classes.Ord Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Generics.Generic Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Internal.ConstrRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Internal.DataRepr'
+ Clash.Annotations.BitRepresentation.Internal: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Internal.Type'
+ Clash.Annotations.BitRepresentation.Internal: thTypeToType' :: Type -> Type'
+ Clash.Annotations.BitRepresentation.Internal: type CustomReprs = (Map Type' DataRepr', Map Text ConstrRepr')
+ Clash.Annotations.BitRepresentation.Util: Field :: Int -> Int -> Int -> BitOrigin
+ Clash.Annotations.BitRepresentation.Util: H :: Bit
+ Clash.Annotations.BitRepresentation.Util: L :: Bit
+ Clash.Annotations.BitRepresentation.Util: Lit :: [Bit] -> BitOrigin
+ Clash.Annotations.BitRepresentation.Util: U :: Bit
+ Clash.Annotations.BitRepresentation.Util: bitOrigins :: DataRepr' -> ConstrRepr' -> [BitOrigin]
+ Clash.Annotations.BitRepresentation.Util: bitOrigins' :: DataRepr' -> ConstrRepr' -> [BitOrigin]
+ Clash.Annotations.BitRepresentation.Util: bitRanges :: Integer -> [(Int, Int)]
+ Clash.Annotations.BitRepresentation.Util: data Bit
+ Clash.Annotations.BitRepresentation.Util: data BitOrigin
+ Clash.Annotations.BitRepresentation.Util: instance GHC.Classes.Eq Clash.Annotations.BitRepresentation.Util.Bit
+ Clash.Annotations.BitRepresentation.Util: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Util.Bit
+ Clash.Annotations.BitRepresentation.Util: instance GHC.Show.Show Clash.Annotations.BitRepresentation.Util.BitOrigin
+ Clash.Annotations.BitRepresentation.Util: isContinuousMask :: Integer -> Bool
+ Clash.Annotations.Primitive: DontTranslate :: PrimitiveGuard a
+ Clash.Annotations.Primitive: HasBlackBox :: a -> PrimitiveGuard a
+ Clash.Annotations.Primitive: WarnAlways :: String -> a -> PrimitiveGuard a
+ Clash.Annotations.Primitive: WarnNonSynthesizable :: String -> a -> PrimitiveGuard a
+ Clash.Annotations.Primitive: data PrimitiveGuard a
+ Clash.Annotations.Primitive: dontTranslate :: PrimitiveGuard ()
+ Clash.Annotations.Primitive: extractPrim :: PrimitiveGuard a -> Maybe a
+ Clash.Annotations.Primitive: hasBlackBox :: PrimitiveGuard ()
+ Clash.Annotations.Primitive: instance Control.DeepSeq.NFData Clash.Annotations.Primitive.HDL
+ Clash.Annotations.Primitive: instance Control.DeepSeq.NFData Clash.Annotations.Primitive.Primitive
+ Clash.Annotations.Primitive: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance Data.Data.Data a => Data.Data.Data (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance Data.Foldable.Foldable Clash.Annotations.Primitive.PrimitiveGuard
+ Clash.Annotations.Primitive: instance Data.Hashable.Class.Hashable Clash.Annotations.Primitive.HDL
+ Clash.Annotations.Primitive: instance Data.Hashable.Class.Hashable Clash.Annotations.Primitive.Primitive
+ Clash.Annotations.Primitive: instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance Data.Traversable.Traversable Clash.Annotations.Primitive.PrimitiveGuard
+ Clash.Annotations.Primitive: instance GHC.Base.Functor Clash.Annotations.Primitive.PrimitiveGuard
+ Clash.Annotations.Primitive: instance GHC.Generics.Generic (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance GHC.Generics.Generic Clash.Annotations.Primitive.HDL
+ Clash.Annotations.Primitive: instance GHC.Generics.Generic Clash.Annotations.Primitive.Primitive
+ Clash.Annotations.Primitive: instance GHC.Read.Read a => GHC.Read.Read (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: instance GHC.Show.Show a => GHC.Show.Show (Clash.Annotations.Primitive.PrimitiveGuard a)
+ Clash.Annotations.Primitive: warnAlways :: String -> PrimitiveGuard ()
+ Clash.Annotations.Primitive: warnNonSynthesizable :: String -> PrimitiveGuard ()
+ Clash.Annotations.SynthesisAttributes: Attr :: Symbol -> Attr
+ Clash.Annotations.SynthesisAttributes: BoolAttr :: Symbol -> Bool -> Attr
+ Clash.Annotations.SynthesisAttributes: IntegerAttr :: Symbol -> Integer -> Attr
+ Clash.Annotations.SynthesisAttributes: StringAttr :: Symbol -> Symbol -> Attr
+ Clash.Annotations.SynthesisAttributes: data Attr
+ Clash.Annotations.SynthesisAttributes: type Annotate (a :: Type) (attrs :: k) = a
+ Clash.Class.BitPack: --
+ Clash.Class.BitPack: -- </pre>
+ Clash.Class.BitPack: -- <pre>
+ Clash.Class.BitPack: -- Can be derived using <a>Generics</a>:
+ Clash.Class.BitPack: -- data MyProductType = MyProductType { a :: Int, b :: Bool }
+ Clash.Class.BitPack: -- deriving (Generic, BitPack)
+ Clash.Class.BitPack: -- import GHC.Generics
+ Clash.Class.BitPack: -- | Number of <a>Bit</a>s needed to represents elements of type <tt>a</tt>
+ Clash.Class.BitPack: instance (Clash.Class.BitPack.BitPack a, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a)) => Clash.Class.BitPack.BitPack (Data.Complex.Complex a)
+ Clash.Class.BitPack: instance (Clash.Class.BitPack.BitPack a, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a)) => Clash.Class.BitPack.BitPack (Data.Ord.Down a)
+ Clash.Class.BitPack: instance (Clash.Class.BitPack.BitPack a, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a)) => Clash.Class.BitPack.BitPack (GHC.Maybe.Maybe a)
+ Clash.Class.BitPack: instance (Clash.Class.BitPack.BitPack a, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a), Clash.Class.BitPack.BitPack b, GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize b)) => Clash.Class.BitPack.BitPack (Data.Either.Either a b)
+ Clash.Class.BitPack: instance (GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize a), GHC.TypeNats.KnownNat (Clash.Class.BitPack.BitSize b), Clash.Class.BitPack.BitPack a, Clash.Class.BitPack.BitPack b) => Clash.Class.BitPack.BitPack (a, b)
+ Clash.Class.BitPack: instance (GHC.TypeNats.KnownNat (Clash.Class.BitPack.GFieldSize g), GHC.TypeNats.KnownNat (Clash.Class.BitPack.GFieldSize f), Clash.Class.BitPack.GBitPack f, Clash.Class.BitPack.GBitPack g) => Clash.Class.BitPack.GBitPack (f GHC.Generics.:*: g)
+ Clash.Class.BitPack: instance (GHC.TypeNats.KnownNat (Clash.Class.BitPack.GFieldSize g), GHC.TypeNats.KnownNat (Clash.Class.BitPack.GFieldSize f), GHC.TypeNats.KnownNat (Clash.Class.BitPack.GConstructorCount f), Clash.Class.BitPack.GBitPack f, Clash.Class.BitPack.GBitPack g) => Clash.Class.BitPack.GBitPack (f GHC.Generics.:+: g)
+ Clash.Class.BitPack: instance Clash.Class.BitPack.GBitPack GHC.Generics.U1
+ Clash.Class.BitPack: instance GHC.TypeNats.KnownNat n => Clash.Class.BitPack.BitPack (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Class.BitPack: packXWith :: KnownNat n => (a -> BitVector n) -> a -> BitVector n
+ Clash.Class.Exp: (^) :: Exp a => a -> SNat n -> ExpResult a n
+ Clash.Class.Exp: class Exp a
+ Clash.Class.Exp: instance GHC.TypeNats.KnownNat m => Clash.Class.Exp.Exp (Clash.Sized.Internal.Index.Index m)
+ Clash.Class.Exp: instance GHC.TypeNats.KnownNat m => Clash.Class.Exp.Exp (Clash.Sized.Internal.Signed.Signed m)
+ Clash.Class.Exp: instance GHC.TypeNats.KnownNat m => Clash.Class.Exp.Exp (Clash.Sized.Internal.Unsigned.Unsigned m)
+ Clash.Class.Exp: type family ExpResult a (n :: Nat)
+ Clash.Class.HasDomain: type WithSingleDomain dom r = (HasSingleDomain r, dom ~ GetDomain r)
+ Clash.Class.HasDomain: type WithSpecificDomain dom r = (HasSpecificDomain dom r, dom ~ GetDomain dom r)
+ Clash.Class.HasDomain.CodeGen: mkHasDomainTuples :: Name -> Name -> Q [Dec]
+ Clash.Class.HasDomain.CodeGen: mkTryDomainTuples :: Name -> Name -> Q [Dec]
+ Clash.Class.HasDomain.Common: infixl 4 :++:
+ Clash.Class.HasDomain.Common: infixl 5 :<<>>:
+ Clash.Class.HasDomain.Common: type (:$$$:) (k1 :: t1) (k2 :: t2) = ToEM k1 :$$: ToEM k2
+ Clash.Class.HasDomain.Common: type family (:++:) (as :: [k]) (bs :: [k]) :: [k]
+ Clash.Class.HasDomain.HasSingleDomain: Ambiguous :: Domain -> Domain -> TryDomainResult
+ Clash.Class.HasDomain.HasSingleDomain: Found :: Domain -> TryDomainResult
+ Clash.Class.HasDomain.HasSingleDomain: NotFound :: TryDomainResult
+ Clash.Class.HasDomain.HasSingleDomain: class HasSingleDomain (r :: Type) where {
+ Clash.Class.HasDomain.HasSingleDomain: data TryDomainResult
+ Clash.Class.HasDomain.HasSingleDomain: instance Clash.Class.HasDomain.HasSingleDomain.HasSingleDomain a
+ Clash.Class.HasDomain.HasSingleDomain: type AmbiguousError (t :: Type) (dom1 :: Domain) (dom2 :: Domain) = "Could not determine that the domain '" :<<>>: dom1 :<<>>: "'" :$$$: "was equal to the domain '" :<<>>: dom2 :<<>>: "' in the type:" :$$$: "" :$$$: " " :<<>>: t :$$$: "" :$$$: "This is usually resolved by adding explicit type signatures." :$$$: Outro
+ Clash.Class.HasDomain.HasSingleDomain: type GetDomain r = IfStuck (TryDomain r r) (DelayError (StuckErrorMsg r r)) (Pure (ErrOnConflict r (TryDomain r r)));
+ Clash.Class.HasDomain.HasSingleDomain: type MissingInstance = "This might happen if an instance for TryDomain is missing. Try to determine" :$$$: "which of the types miss an instance, and add them. Example implementations:" :$$$: "" :$$$: " * type instance TryDomain t (MyVector n a) = TryDomain t a" :$$$: " * type instance TryDomain t (MyCircuit dom a) = Found dom" :$$$: " * type instance TryDomain t Terminal = NotFound" :$$$: "" :$$$: "Alternatively, use one of the withSpecific* functions."
+ Clash.Class.HasDomain.HasSingleDomain: type NotFoundError (t :: Type) = "Could not find a non-ambiguous domain in the following type:" :$$$: "" :$$$: " " :<<>>: t :$$$: "" :$$$: MissingInstance :$$$: Outro
+ Clash.Class.HasDomain.HasSingleDomain: type Outro = "" :$$$: "------" :$$$: "" :$$$: "You tried to apply an explicitly routed clock, reset, or enable line" :$$$: "to a construct with, possibly, an implicitly routed one. Clash failed to" :$$$: "unambigously determine a single domain and could therefore not route it." :$$$: "You possibly used one of these sets of functions:" :$$$: "" :$$$: " * with{ClockResetEnable,Clock,Reset,Enable}" :$$$: " * expose{ClockResetEnable,Clock,Reset,Enable}" :$$$: "" :$$$: "These functions are suitable for components defined over a single domain" :$$$: "only. If you want to use multiple domains, use the following instead:" :$$$: "" :$$$: " * withSpecific{ClockResetEnable,Clock,Reset,Enable}" :$$$: " * exposeSpecific{ClockResetEnable,Clock,Reset,Enable}" :$$$: ""
+ Clash.Class.HasDomain.HasSingleDomain: type StuckErrorMsg (orig :: Type) (n :: Type) = "Could not determine whether the following type contained a non-ambiguous domain:" :$$$: "" :$$$: " " :<<>>: n :$$$: "" :$$$: "In the full type:" :$$$: "" :$$$: " " :<<>>: orig :$$$: "" :$$$: "Does it contain one?" :$$$: "" :$$$: "------" :$$$: "" :$$$: MissingInstance :$$$: Outro
+ Clash.Class.HasDomain.HasSingleDomain: type WithSingleDomain dom r = (HasSingleDomain r, dom ~ GetDomain r)
+ Clash.Class.HasDomain.HasSingleDomain: type family GetDomain r :: Domain;
+ Clash.Class.HasDomain.HasSingleDomain: }
+ Clash.Class.HasDomain.HasSpecificDomain: Found :: HasDomainWrapperResult
+ Clash.Class.HasDomain.HasSpecificDomain: NotFound :: HasDomainWrapperResult
+ Clash.Class.HasDomain.HasSpecificDomain: class HasSpecificDomain (dom :: Domain) (r :: Type) where {
+ Clash.Class.HasDomain.HasSpecificDomain: data HasDomainWrapperResult
+ Clash.Class.HasDomain.HasSpecificDomain: instance Clash.Class.HasDomain.HasSpecificDomain.HasSpecificDomain dom a
+ Clash.Class.HasDomain.HasSpecificDomain: type DomEq (n :: Domain) (m :: Domain) = IfStuck (DomEqWorker n m) ('NotFound) (Pure (DomEqWorker n m))
+ Clash.Class.HasDomain.HasSpecificDomain: type GetDomain dom r = ResolveOrErr dom r;
+ Clash.Class.HasDomain.HasSpecificDomain: type Merge (dom :: Domain) (n :: Type) (m :: Type) = MergeWorker (HasDomainWrapper dom n) (HasDomainWrapper dom m)
+ Clash.Class.HasDomain.HasSpecificDomain: type NotFoundError (dom :: Domain) (t :: Type) = "Could not find domain '" :<<>>: 'ShowType dom :<<>>: "' in the following type:" :$$$: "" :$$$: " " :<<>>: t :$$$: "" :$$$: "If that type contains that domain anyway, you might need to provide an" :$$$: "additional type instance of HasDomain. Example implementations:" :$$$: "" :$$$: " * type instance HasDomain dom (MyVector n a) = HasDomain dom a" :$$$: " * type instance HasDomain dom1 (MyCircuit dom2 a) = DomEq dom1 dom2" :$$$: " * type instance HasDomain dom1 (MyTuple a b) = Merge dom a b" :$$$: "" :$$$: Outro
+ Clash.Class.HasDomain.HasSpecificDomain: type Outro = "" :$$$: "------" :$$$: "" :$$$: "You tried to apply an explicitly routed clock, reset, or enable line" :$$$: "to a construct with, possibly, an implicitly routed one. Clash failed to" :$$$: "unambigously link the given domain (by passing in a 'Clock', 'Reset', or" :$$$: "'Enable') to the component passed in." :$$$: ""
+ Clash.Class.HasDomain.HasSpecificDomain: type WithSpecificDomain dom r = (HasSpecificDomain dom r, dom ~ GetDomain dom r)
+ Clash.Class.HasDomain.HasSpecificDomain: type family GetDomain dom r :: Domain;
+ Clash.Class.HasDomain.HasSpecificDomain: }
+ Clash.Class.Num: -- | Type of the result of the multiplication
+ Clash.Class.Num: add :: ExtendingNum a b => a -> b -> AResult a b
+ Clash.Class.Num: boundedAdd :: SaturatingNum a => a -> a -> a
+ Clash.Class.Num: boundedMul :: SaturatingNum a => a -> a -> a
+ Clash.Class.Num: boundedSub :: SaturatingNum a => a -> a -> a
+ Clash.Class.Num: mul :: ExtendingNum a b => a -> b -> MResult a b
+ Clash.Class.Num: satAdd :: SaturatingNum a => SaturationMode -> a -> a -> a
+ Clash.Class.Num: satMul :: SaturatingNum a => SaturationMode -> a -> a -> a
+ Clash.Class.Num: satPred :: SaturatingNum a => SaturationMode -> a -> a
+ Clash.Class.Num: satSub :: SaturatingNum a => SaturationMode -> a -> a -> a
+ Clash.Class.Num: satSucc :: SaturatingNum a => SaturationMode -> a -> a
+ Clash.Class.Num: sub :: ExtendingNum a b => a -> b -> AResult a b
+ Clash.Clocks: class Clocks t
+ Clash.Clocks: clocks :: Clocks t => Clock domIn -> Reset domIn -> t
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Clock c15, Clash.Signal.Internal.Clock c16, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Clock c15, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks.Deriving: deriveClocksInstances :: Int -> Q [Dec]
+ Clash.Examples: instance Clash.XException.NFDataX Clash.Examples.RxReg
+ Clash.Examples: instance Clash.XException.NFDataX Clash.Examples.TxReg
+ Clash.Examples: instance GHC.Generics.Generic Clash.Examples.RxReg
+ Clash.Examples: instance GHC.Generics.Generic Clash.Examples.TxReg
+ Clash.Explicit.BlockRam: [ClearOnReset] :: ResetStrategy 'True
+ Clash.Explicit.BlockRam: [NoClearOnReset] :: ResetStrategy 'False
+ Clash.Explicit.BlockRam: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: data ResetStrategy (r :: Bool)
+ Clash.Explicit.Prelude: [ClearOnReset] :: ResetStrategy 'True
+ Clash.Explicit.Prelude: [NoClearOnReset] :: ResetStrategy 'False
+ Clash.Explicit.Prelude: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: class Generic a
+ Clash.Explicit.Prelude: class Generic1 (f :: k -> Type)
+ Clash.Explicit.Prelude: data ResetStrategy (r :: Bool)
+ Clash.Explicit.Prelude: dumpVCD :: NFDataX a => (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
+ Clash.Explicit.Prelude: outputVerifier' :: forall l a dom. (KnownNat l, KnownDomain dom, DomainResetKind dom ~ 'Asynchronous, Eq a, ShowX a) => Clock dom -> Reset dom -> Vec l a -> Signal dom a -> Signal dom Bool
+ Clash.Explicit.Prelude: traceSignal :: forall dom a. (KnownDomain dom, KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Explicit.Prelude: traceSignal1 :: (KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Explicit.Prelude: traceVecSignal :: forall dom a n. (KnownDomain dom, KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Explicit.Prelude: traceVecSignal1 :: (KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Explicit.Prelude.Safe: class Generic a
+ Clash.Explicit.Prelude.Safe: class Generic1 (f :: k -> Type)
+ Clash.Explicit.Signal: ActiveHigh :: ResetPolarity
+ Clash.Explicit.Signal: ActiveLow :: ResetPolarity
+ Clash.Explicit.Signal: Defined :: InitBehavior
+ Clash.Explicit.Signal: DomainConfiguration :: Domain -> Nat -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> DomainConfiguration
+ Clash.Explicit.Signal: Enable :: Signal dom Bool -> Enable dom
+ Clash.Explicit.Signal: Falling :: ActiveEdge
+ Clash.Explicit.Signal: Reset :: Signal dom Bool -> Reset (dom :: Domain)
+ Clash.Explicit.Signal: Rising :: ActiveEdge
+ Clash.Explicit.Signal: Unknown :: InitBehavior
+ Clash.Explicit.Signal: VDomainConfiguration :: String -> Natural -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> VDomainConfiguration
+ Clash.Explicit.Signal: [SActiveHigh] :: SResetPolarity 'ActiveHigh
+ Clash.Explicit.Signal: [SActiveLow] :: SResetPolarity 'ActiveLow
+ Clash.Explicit.Signal: [SAsynchronous] :: SResetKind 'Asynchronous
+ Clash.Explicit.Signal: [SDefined] :: SInitBehavior 'Defined
+ Clash.Explicit.Signal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Explicit.Signal: [SFalling] :: SActiveEdge 'Falling
+ Clash.Explicit.Signal: [SRising] :: SActiveEdge 'Rising
+ Clash.Explicit.Signal: [SSynchronous] :: SResetKind 'Synchronous
+ Clash.Explicit.Signal: [SUnknown] :: SInitBehavior 'Unknown
+ Clash.Explicit.Signal: [_activeEdge] :: DomainConfiguration -> ActiveEdge
+ Clash.Explicit.Signal: [_initBehavior] :: DomainConfiguration -> InitBehavior
+ Clash.Explicit.Signal: [_name] :: DomainConfiguration -> Domain
+ Clash.Explicit.Signal: [_period] :: DomainConfiguration -> Nat
+ Clash.Explicit.Signal: [_resetKind] :: DomainConfiguration -> ResetKind
+ Clash.Explicit.Signal: [_resetPolarity] :: DomainConfiguration -> ResetPolarity
+ Clash.Explicit.Signal: [vActiveEdge] :: VDomainConfiguration -> ActiveEdge
+ Clash.Explicit.Signal: [vInitBehavior] :: VDomainConfiguration -> InitBehavior
+ Clash.Explicit.Signal: [vName] :: VDomainConfiguration -> String
+ Clash.Explicit.Signal: [vPeriod] :: VDomainConfiguration -> Natural
+ Clash.Explicit.Signal: [vResetKind] :: VDomainConfiguration -> ResetKind
+ Clash.Explicit.Signal: [vResetPolarity] :: VDomainConfiguration -> ResetPolarity
+ Clash.Explicit.Signal: activeEdge :: forall dom edge. (KnownDomain dom, DomainActiveEdge dom ~ edge) => SActiveEdge edge
+ Clash.Explicit.Signal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Explicit.Signal: clockPeriod :: forall dom period. (KnownDomain dom, DomainPeriod dom ~ period) => SNat period
+ Clash.Explicit.Signal: convertReset :: forall domA domB. (KnownDomain domA, KnownDomain domB) => Clock domA -> Clock domB -> Reset domA -> Reset domB
+ Clash.Explicit.Signal: createDomain :: VDomainConfiguration -> Q [Dec]
+ Clash.Explicit.Signal: data ActiveEdge
+ Clash.Explicit.Signal: data DomainConfiguration
+ Clash.Explicit.Signal: data InitBehavior
+ Clash.Explicit.Signal: data ResetPolarity
+ Clash.Explicit.Signal: data SActiveEdge (edge :: ActiveEdge)
+ Clash.Explicit.Signal: data SDomainConfiguration (dom :: Domain) (conf :: DomainConfiguration)
+ Clash.Explicit.Signal: data SInitBehavior (init :: InitBehavior)
+ Clash.Explicit.Signal: data SResetKind (resetKind :: ResetKind)
+ Clash.Explicit.Signal: data SResetPolarity (polarity :: ResetPolarity)
+ Clash.Explicit.Signal: data VDomainConfiguration
+ Clash.Explicit.Signal: delayEn :: (KnownDomain dom, NFDataX a) => Clock dom -> Enable dom -> a -> Signal dom Bool -> Signal dom a -> Signal dom a
+ Clash.Explicit.Signal: delayMaybe :: (KnownDomain dom, NFDataX a) => Clock dom -> Enable dom -> a -> Signal dom (Maybe a) -> Signal dom a
+ Clash.Explicit.Signal: dflipflop :: (KnownDomain dom, NFDataX a) => Clock dom -> Signal dom a -> Signal dom a
+ Clash.Explicit.Signal: enable :: Enable dom -> Signal dom Bool -> Enable dom
+ Clash.Explicit.Signal: enableGen :: Enable dom
+ Clash.Explicit.Signal: fromEnable :: Enable dom -> Signal dom Bool
+ Clash.Explicit.Signal: fromListWithReset :: forall dom a. (KnownDomain dom, NFDataX a) => Reset dom -> a -> [a] -> Signal dom a
+ Clash.Explicit.Signal: holdReset :: forall dom n. KnownDomain dom => Clock dom -> Enable dom -> SNat n -> Reset dom -> Reset dom
+ Clash.Explicit.Signal: hzToPeriod :: HasCallStack => Double -> Natural
+ Clash.Explicit.Signal: initBehavior :: forall dom init. (KnownDomain dom, DomainInitBehavior dom ~ init) => SInitBehavior init
+ Clash.Explicit.Signal: knownDomain :: KnownDomain dom => SDomainConfiguration dom (KnownConf dom)
+ Clash.Explicit.Signal: knownVDomain :: forall dom. KnownDomain dom => VDomainConfiguration
+ Clash.Explicit.Signal: newtype Enable dom
+ Clash.Explicit.Signal: periodToHz :: Natural -> Double
+ Clash.Explicit.Signal: resetGen :: forall dom. KnownDomain dom => Reset dom
+ Clash.Explicit.Signal: resetGenN :: forall dom n. (KnownDomain dom, 1 <= n) => SNat n -> Reset dom
+ Clash.Explicit.Signal: resetKind :: forall dom sync. (KnownDomain dom, DomainResetKind dom ~ sync) => SResetKind sync
+ Clash.Explicit.Signal: resetPolarity :: forall dom polarity. (KnownDomain dom, DomainResetPolarity dom ~ polarity) => SResetPolarity polarity
+ Clash.Explicit.Signal: simulateWithReset :: forall dom a b m. (KnownDomain dom, NFDataX a, NFDataX b, 1 <= m) => SNat m -> a -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Signal dom b) -> [a] -> [b]
+ Clash.Explicit.Signal: simulateWithResetN :: (KnownDomain dom, NFDataX a, NFDataX b, 1 <= m) => SNat m -> a -> Int -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Signal dom b) -> [a] -> [b]
+ Clash.Explicit.Signal: toEnable :: Signal dom Bool -> Enable dom
+ Clash.Explicit.Signal: type Domain = Symbol
+ Clash.Explicit.Signal: type DomainActiveEdge (dom :: Domain) = DomainConfigurationActiveEdge (KnownConf dom)
+ Clash.Explicit.Signal: type DomainInitBehavior (dom :: Domain) = DomainConfigurationInitBehavior (KnownConf dom)
+ Clash.Explicit.Signal: type DomainPeriod (dom :: Domain) = DomainConfigurationPeriod (KnownConf dom)
+ Clash.Explicit.Signal: type DomainResetKind (dom :: Domain) = DomainConfigurationResetKind (KnownConf dom)
+ Clash.Explicit.Signal: type DomainResetPolarity (dom :: Domain) = DomainConfigurationResetPolarity (KnownConf dom)
+ Clash.Explicit.Signal: type IntelSystem = ("IntelSystem" :: Domain)
+ Clash.Explicit.Signal: type KnownConfiguration dom conf = (KnownDomain dom, KnownConf dom ~ conf)
+ Clash.Explicit.Signal: type XilinxSystem = ("XilinxSystem" :: Domain)
+ Clash.Explicit.Signal: unsafeFromHighPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: unsafeFromLowPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: unsafeFromReset :: Reset dom -> Signal dom Bool
+ Clash.Explicit.Signal: unsafeToHighPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Signal: unsafeToLowPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Signal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: vDomain :: SDomainConfiguration dom conf -> VDomainConfiguration
+ Clash.Explicit.Signal: vIntelSystem :: VDomainConfiguration
+ Clash.Explicit.Signal: vSystem :: VDomainConfiguration
+ Clash.Explicit.Signal: vXilinxSystem :: VDomainConfiguration
+ Clash.Explicit.Signal: veryUnsafeSynchronizer :: Int -> Int -> Signal dom1 a -> Signal dom2 a
+ Clash.Explicit.Testbench: biTbClockGen :: forall testDom circuitDom. (KnownDomain testDom, KnownDomain circuitDom, DomainResetKind testDom ~ 'Asynchronous) => Signal testDom Bool -> (Clock testDom, Clock circuitDom)
+ Clash.Explicit.Testbench: ignoreFor :: forall dom n a. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> SNat n -> a -> Signal dom a -> Signal dom a
+ Clash.Explicit.Testbench: outputVerifier' :: forall l a dom. (KnownNat l, KnownDomain dom, DomainResetKind dom ~ 'Asynchronous, Eq a, ShowX a) => Clock dom -> Reset dom -> Vec l a -> Signal dom a -> Signal dom Bool
+ Clash.Explicit.Testbench: outputVerifierBitVector :: forall l n testDom circuitDom. (KnownNat l, KnownNat n, KnownDomain testDom, KnownDomain circuitDom, DomainResetKind testDom ~ 'Asynchronous) => Clock testDom -> Reset testDom -> Vec l (BitVector n) -> Signal circuitDom (BitVector n) -> Signal testDom Bool
+ Clash.Explicit.Testbench: outputVerifierBitVector' :: forall l n dom. (KnownNat l, KnownNat n, KnownDomain dom, DomainResetKind dom ~ 'Asynchronous) => Clock dom -> Reset dom -> Vec l (BitVector n) -> Signal dom (BitVector n) -> Signal dom Bool
+ Clash.Explicit.Testbench: tbClockGen :: KnownDomain testDom => Signal testDom Bool -> Clock testDom
+ Clash.Explicit.Testbench: tbEnableGen :: Enable tag
+ Clash.Explicit.Testbench: tbSystemClockGen :: Signal System Bool -> Clock System
+ Clash.HaskellPrelude: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Clash.HaskellPrelude: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Clash.HaskellPrelude: (&&) :: Bool -> Bool -> Bool
+ Clash.HaskellPrelude: (*) :: Num a => a -> a -> a
+ Clash.HaskellPrelude: (**) :: Floating a => a -> a -> a
+ Clash.HaskellPrelude: (*>) :: Applicative f => f a -> f b -> f b
+ Clash.HaskellPrelude: (+) :: Num a => a -> a -> a
+ Clash.HaskellPrelude: (-) :: Num a => a -> a -> a
+ Clash.HaskellPrelude: (.) :: (b -> c) -> (a -> b) -> a -> c
+ Clash.HaskellPrelude: (/) :: Fractional a => a -> a -> a
+ Clash.HaskellPrelude: (/=) :: Eq a => a -> a -> Bool
+ Clash.HaskellPrelude: (<$) :: Functor f => a -> f b -> f a
+ Clash.HaskellPrelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Clash.HaskellPrelude: (<) :: Ord a => a -> a -> Bool
+ Clash.HaskellPrelude: (<*) :: Applicative f => f a -> f b -> f a
+ Clash.HaskellPrelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ Clash.HaskellPrelude: (<=) :: Ord a => a -> a -> Bool
+ Clash.HaskellPrelude: (<>) :: Semigroup a => a -> a -> a
+ Clash.HaskellPrelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Clash.HaskellPrelude: (==) :: Eq a => a -> a -> Bool
+ Clash.HaskellPrelude: (>) :: Ord a => a -> a -> Bool
+ Clash.HaskellPrelude: (>=) :: Ord a => a -> a -> Bool
+ Clash.HaskellPrelude: (>>) :: Monad m => m a -> m b -> m b
+ Clash.HaskellPrelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Clash.HaskellPrelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Clash.HaskellPrelude: (||) :: Bool -> Bool -> Bool
+ Clash.HaskellPrelude: EQ :: Ordering
+ Clash.HaskellPrelude: False :: Bool
+ Clash.HaskellPrelude: GT :: Ordering
+ Clash.HaskellPrelude: Just :: a -> Maybe a
+ Clash.HaskellPrelude: LT :: Ordering
+ Clash.HaskellPrelude: Left :: a -> Either a b
+ Clash.HaskellPrelude: Nothing :: Maybe a
+ Clash.HaskellPrelude: Right :: b -> Either a b
+ Clash.HaskellPrelude: True :: Bool
+ Clash.HaskellPrelude: abs :: Num a => a -> a
+ Clash.HaskellPrelude: acos :: Floating a => a -> a
+ Clash.HaskellPrelude: acosh :: Floating a => a -> a
+ Clash.HaskellPrelude: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ Clash.HaskellPrelude: and :: Foldable t => t Bool -> Bool
+ Clash.HaskellPrelude: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ Clash.HaskellPrelude: appendFile :: FilePath -> String -> IO ()
+ Clash.HaskellPrelude: asTypeOf :: a -> a -> a
+ Clash.HaskellPrelude: asin :: Floating a => a -> a
+ Clash.HaskellPrelude: asinh :: Floating a => a -> a
+ Clash.HaskellPrelude: atan :: Floating a => a -> a
+ Clash.HaskellPrelude: atan2 :: RealFloat a => a -> a -> a
+ Clash.HaskellPrelude: atanh :: Floating a => a -> a
+ Clash.HaskellPrelude: break :: (a -> Bool) -> [a] -> ([a], [a])
+ Clash.HaskellPrelude: ceiling :: (RealFrac a, Integral b) => a -> b
+ Clash.HaskellPrelude: class Functor f => Applicative (f :: Type -> Type)
+ Clash.HaskellPrelude: class Bounded a
+ Clash.HaskellPrelude: class Enum a
+ Clash.HaskellPrelude: class Eq a
+ Clash.HaskellPrelude: class Fractional a => Floating a
+ Clash.HaskellPrelude: class Foldable (t :: Type -> Type)
+ Clash.HaskellPrelude: class Num a => Fractional a
+ Clash.HaskellPrelude: class Functor (f :: Type -> Type)
+ Clash.HaskellPrelude: class (Real a, Enum a) => Integral a
+ Clash.HaskellPrelude: class Applicative m => Monad (m :: Type -> Type)
+ Clash.HaskellPrelude: class Monad m => MonadFail (m :: Type -> Type)
+ Clash.HaskellPrelude: class Semigroup a => Monoid a
+ Clash.HaskellPrelude: class Num a
+ Clash.HaskellPrelude: class Eq a => Ord a
+ Clash.HaskellPrelude: class Read a
+ Clash.HaskellPrelude: class (Num a, Ord a) => Real a
+ Clash.HaskellPrelude: class (RealFrac a, Floating a) => RealFloat a
+ Clash.HaskellPrelude: class (Real a, Fractional a) => RealFrac a
+ Clash.HaskellPrelude: class Semigroup a
+ Clash.HaskellPrelude: class Show a
+ Clash.HaskellPrelude: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ Clash.HaskellPrelude: compare :: Ord a => a -> a -> Ordering
+ Clash.HaskellPrelude: const :: a -> b -> a
+ Clash.HaskellPrelude: cos :: Floating a => a -> a
+ Clash.HaskellPrelude: cosh :: Floating a => a -> a
+ Clash.HaskellPrelude: curry :: ((a, b) -> c) -> a -> b -> c
+ Clash.HaskellPrelude: cycle :: [a] -> [a]
+ Clash.HaskellPrelude: data Bool
+ Clash.HaskellPrelude: data Char
+ Clash.HaskellPrelude: data Double
+ Clash.HaskellPrelude: data Either a b
+ Clash.HaskellPrelude: data Float
+ Clash.HaskellPrelude: data IO a
+ Clash.HaskellPrelude: data Int
+ Clash.HaskellPrelude: data Integer
+ Clash.HaskellPrelude: data Maybe a
+ Clash.HaskellPrelude: data Ordering
+ Clash.HaskellPrelude: data Word
+ Clash.HaskellPrelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Clash.HaskellPrelude: div :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: divMod :: Integral a => a -> a -> (a, a)
+ Clash.HaskellPrelude: dropWhile :: (a -> Bool) -> [a] -> [a]
+ Clash.HaskellPrelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
+ Clash.HaskellPrelude: elem :: (Foldable t, Eq a) => a -> t a -> Bool
+ Clash.HaskellPrelude: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Clash.HaskellPrelude: enumFrom :: Enum a => a -> [a]
+ Clash.HaskellPrelude: enumFromThen :: Enum a => a -> a -> [a]
+ Clash.HaskellPrelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Clash.HaskellPrelude: enumFromTo :: Enum a => a -> a -> [a]
+ Clash.HaskellPrelude: error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => [Char] -> a
+ Clash.HaskellPrelude: errorWithoutStackTrace :: forall (r :: RuntimeRep) (a :: TYPE r). [Char] -> a
+ Clash.HaskellPrelude: even :: Integral a => a -> Bool
+ Clash.HaskellPrelude: exp :: Floating a => a -> a
+ Clash.HaskellPrelude: exponent :: RealFloat a => a -> Int
+ Clash.HaskellPrelude: fail :: MonadFail m => String -> m a
+ Clash.HaskellPrelude: filter :: (a -> Bool) -> [a] -> [a]
+ Clash.HaskellPrelude: flip :: (a -> b -> c) -> b -> a -> c
+ Clash.HaskellPrelude: floatDigits :: RealFloat a => a -> Int
+ Clash.HaskellPrelude: floatRadix :: RealFloat a => a -> Integer
+ Clash.HaskellPrelude: floatRange :: RealFloat a => a -> (Int, Int)
+ Clash.HaskellPrelude: floor :: (RealFrac a, Integral b) => a -> b
+ Clash.HaskellPrelude: fmap :: Functor f => (a -> b) -> f a -> f b
+ Clash.HaskellPrelude: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Clash.HaskellPrelude: fromEnum :: Enum a => a -> Int
+ Clash.HaskellPrelude: fromInteger :: Num a => Integer -> a
+ Clash.HaskellPrelude: fromIntegral :: (Integral a, Num b) => a -> b
+ Clash.HaskellPrelude: fromRational :: Fractional a => Rational -> a
+ Clash.HaskellPrelude: fst :: (a, b) -> a
+ Clash.HaskellPrelude: gcd :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: getChar :: IO Char
+ Clash.HaskellPrelude: getContents :: IO String
+ Clash.HaskellPrelude: getLine :: IO String
+ Clash.HaskellPrelude: id :: a -> a
+ Clash.HaskellPrelude: infix 4 `notElem`
+ Clash.HaskellPrelude: infixl 1 >>
+ Clash.HaskellPrelude: infixl 4 <$>
+ Clash.HaskellPrelude: infixl 6 -
+ Clash.HaskellPrelude: infixl 7 *
+ Clash.HaskellPrelude: infixr 0 $!
+ Clash.HaskellPrelude: infixr 1 =<<
+ Clash.HaskellPrelude: infixr 2 ||
+ Clash.HaskellPrelude: infixr 3 &&
+ Clash.HaskellPrelude: infixr 6 <>
+ Clash.HaskellPrelude: infixr 8 ^^
+ Clash.HaskellPrelude: infixr 9 .
+ Clash.HaskellPrelude: interact :: (String -> String) -> IO ()
+ Clash.HaskellPrelude: ioError :: IOError -> IO a
+ Clash.HaskellPrelude: isDenormalized :: RealFloat a => a -> Bool
+ Clash.HaskellPrelude: isIEEE :: RealFloat a => a -> Bool
+ Clash.HaskellPrelude: isInfinite :: RealFloat a => a -> Bool
+ Clash.HaskellPrelude: isNaN :: RealFloat a => a -> Bool
+ Clash.HaskellPrelude: isNegativeZero :: RealFloat a => a -> Bool
+ Clash.HaskellPrelude: lcm :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: lex :: ReadS String
+ Clash.HaskellPrelude: lines :: String -> [String]
+ Clash.HaskellPrelude: log :: Floating a => a -> a
+ Clash.HaskellPrelude: logBase :: Floating a => a -> a -> a
+ Clash.HaskellPrelude: lookup :: Eq a => a -> [(a, b)] -> Maybe b
+ Clash.HaskellPrelude: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ Clash.HaskellPrelude: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ Clash.HaskellPrelude: mappend :: Monoid a => a -> a -> a
+ Clash.HaskellPrelude: max :: Ord a => a -> a -> a
+ Clash.HaskellPrelude: maxBound :: Bounded a => a
+ Clash.HaskellPrelude: maximum :: (Foldable t, Ord a) => t a -> a
+ Clash.HaskellPrelude: maybe :: b -> (a -> b) -> Maybe a -> b
+ Clash.HaskellPrelude: mconcat :: Monoid a => [a] -> a
+ Clash.HaskellPrelude: mempty :: Monoid a => a
+ Clash.HaskellPrelude: min :: Ord a => a -> a -> a
+ Clash.HaskellPrelude: minBound :: Bounded a => a
+ Clash.HaskellPrelude: minimum :: (Foldable t, Ord a) => t a -> a
+ Clash.HaskellPrelude: mod :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: negate :: Num a => a -> a
+ Clash.HaskellPrelude: not :: Bool -> Bool
+ Clash.HaskellPrelude: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
+ Clash.HaskellPrelude: null :: Foldable t => t a -> Bool
+ Clash.HaskellPrelude: odd :: Integral a => a -> Bool
+ Clash.HaskellPrelude: or :: Foldable t => t Bool -> Bool
+ Clash.HaskellPrelude: otherwise :: Bool
+ Clash.HaskellPrelude: pi :: Floating a => a
+ Clash.HaskellPrelude: pred :: Enum a => a -> a
+ Clash.HaskellPrelude: print :: Show a => a -> IO ()
+ Clash.HaskellPrelude: product :: (Foldable t, Num a) => t a -> a
+ Clash.HaskellPrelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Clash.HaskellPrelude: pure :: Applicative f => a -> f a
+ Clash.HaskellPrelude: putChar :: Char -> IO ()
+ Clash.HaskellPrelude: putStr :: String -> IO ()
+ Clash.HaskellPrelude: putStrLn :: String -> IO ()
+ Clash.HaskellPrelude: quot :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: quotRem :: Integral a => a -> a -> (a, a)
+ Clash.HaskellPrelude: read :: Read a => String -> a
+ Clash.HaskellPrelude: readFile :: FilePath -> IO String
+ Clash.HaskellPrelude: readIO :: Read a => String -> IO a
+ Clash.HaskellPrelude: readList :: Read a => ReadS [a]
+ Clash.HaskellPrelude: readLn :: Read a => IO a
+ Clash.HaskellPrelude: readParen :: Bool -> ReadS a -> ReadS a
+ Clash.HaskellPrelude: reads :: Read a => ReadS a
+ Clash.HaskellPrelude: readsPrec :: Read a => Int -> ReadS a
+ Clash.HaskellPrelude: realToFrac :: (Real a, Fractional b) => a -> b
+ Clash.HaskellPrelude: recip :: Fractional a => a -> a
+ Clash.HaskellPrelude: rem :: Integral a => a -> a -> a
+ Clash.HaskellPrelude: return :: Monad m => a -> m a
+ Clash.HaskellPrelude: round :: (RealFrac a, Integral b) => a -> b
+ Clash.HaskellPrelude: scaleFloat :: RealFloat a => Int -> a -> a
+ Clash.HaskellPrelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
+ Clash.HaskellPrelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
+ Clash.HaskellPrelude: seq :: a -> b -> b
+ Clash.HaskellPrelude: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ Clash.HaskellPrelude: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ Clash.HaskellPrelude: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ Clash.HaskellPrelude: show :: Show a => a -> String
+ Clash.HaskellPrelude: showChar :: Char -> ShowS
+ Clash.HaskellPrelude: showList :: Show a => [a] -> ShowS
+ Clash.HaskellPrelude: showParen :: Bool -> ShowS -> ShowS
+ Clash.HaskellPrelude: showString :: String -> ShowS
+ Clash.HaskellPrelude: shows :: Show a => a -> ShowS
+ Clash.HaskellPrelude: showsPrec :: Show a => Int -> a -> ShowS
+ Clash.HaskellPrelude: significand :: RealFloat a => a -> a
+ Clash.HaskellPrelude: signum :: Num a => a -> a
+ Clash.HaskellPrelude: sin :: Floating a => a -> a
+ Clash.HaskellPrelude: sinh :: Floating a => a -> a
+ Clash.HaskellPrelude: snd :: (a, b) -> b
+ Clash.HaskellPrelude: span :: (a -> Bool) -> [a] -> ([a], [a])
+ Clash.HaskellPrelude: sqrt :: Floating a => a -> a
+ Clash.HaskellPrelude: subtract :: Num a => a -> a -> a
+ Clash.HaskellPrelude: succ :: Enum a => a -> a
+ Clash.HaskellPrelude: sum :: (Foldable t, Num a) => t a -> a
+ Clash.HaskellPrelude: takeWhile :: (a -> Bool) -> [a] -> [a]
+ Clash.HaskellPrelude: tan :: Floating a => a -> a
+ Clash.HaskellPrelude: tanh :: Floating a => a -> a
+ Clash.HaskellPrelude: toEnum :: Enum a => Int -> a
+ Clash.HaskellPrelude: toInteger :: Integral a => a -> Integer
+ Clash.HaskellPrelude: toRational :: Real a => a -> Rational
+ Clash.HaskellPrelude: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Clash.HaskellPrelude: truncate :: (RealFrac a, Integral b) => a -> b
+ Clash.HaskellPrelude: type FilePath = String
+ Clash.HaskellPrelude: type IOError = IOException
+ Clash.HaskellPrelude: type Rational = Ratio Integer
+ Clash.HaskellPrelude: type ReadS a = String -> [(a, String)]
+ Clash.HaskellPrelude: type ShowS = String -> String
+ Clash.HaskellPrelude: type String = [Char]
+ Clash.HaskellPrelude: uncurry :: (a -> b -> c) -> (a, b) -> c
+ Clash.HaskellPrelude: unlines :: [String] -> String
+ Clash.HaskellPrelude: until :: (a -> Bool) -> (a -> a) -> a -> a
+ Clash.HaskellPrelude: unwords :: [String] -> String
+ Clash.HaskellPrelude: userError :: String -> IOError
+ Clash.HaskellPrelude: words :: String -> [String]
+ Clash.HaskellPrelude: writeFile :: FilePath -> String -> IO ()
+ Clash.Magic: prefixName :: forall (name :: Symbol) a. a -> name ::: a
+ Clash.Magic: setName :: forall (name :: Symbol) a. a -> name ::: a
+ Clash.Magic: suffixName :: forall (name :: Symbol) a. a -> name ::: a
+ Clash.Prelude: [ClearOnReset] :: ResetStrategy 'True
+ Clash.Prelude: [NoClearOnReset] :: ResetStrategy 'False
+ Clash.Prelude: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: class Generic a
+ Clash.Prelude: class Generic1 (f :: k -> Type)
+ Clash.Prelude: data ResetStrategy (r :: Bool)
+ Clash.Prelude: dumpVCD :: NFDataX a => (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
+ Clash.Prelude: traceSignal :: forall dom a. (KnownDomain dom, KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Prelude: traceSignal1 :: (KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Prelude: traceVecSignal :: forall dom a n. (KnownDomain dom, KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Prelude: traceVecSignal1 :: (KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Prelude.BlockRam: [ClearOnReset] :: ResetStrategy 'True
+ Clash.Prelude.BlockRam: [NoClearOnReset] :: ResetStrategy 'False
+ Clash.Prelude.BlockRam: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.BlockRam: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.BlockRam: data ResetStrategy (r :: Bool)
+ Clash.Prelude.Safe: class Generic a
+ Clash.Prelude.Safe: class Generic1 (f :: k -> Type)
+ Clash.Prelude.Testbench: ignoreFor :: HiddenClockResetEnable dom => SNat n -> a -> Signal dom a -> Signal dom a
+ Clash.Prelude.Testbench: outputVerifier' :: (KnownNat l, Eq a, ShowX a, DomainResetKind dom ~ 'Asynchronous, HiddenClock dom, HiddenReset dom) => Vec l a -> Signal dom a -> Signal dom Bool
+ Clash.Prelude.Testbench: outputVerifierBitVector' :: (KnownNat l, KnownNat n, DomainResetKind dom ~ 'Asynchronous, HiddenClock dom, HiddenReset dom) => Vec l (BitVector n) -> Signal dom (BitVector n) -> Signal dom Bool
+ Clash.Prelude.Testbench: tbClockGen :: KnownDomain testDom => Signal testDom Bool -> Clock testDom
+ Clash.Prelude.Testbench: tbEnableGen :: Enable tag
+ Clash.Prelude.Testbench: tbSystemClockGen :: Signal System Bool -> Clock System
+ Clash.Promoted.Nat: [SNatGT] :: forall a b. (b + 1) <= a => SNatLE a b
+ Clash.Promoted.Nat: [SNatLE] :: forall a b. a <= b => SNatLE a b
+ Clash.Promoted.Nat: compareSNat :: forall a b. SNat a -> SNat b -> SNatLE a b
+ Clash.Promoted.Nat: data SNatLE a b
+ Clash.Promoted.Nat: maxSNat :: SNat a -> SNat b -> SNat (Max a b)
+ Clash.Promoted.Nat: minSNat :: SNat a -> SNat b -> SNat (Min a b)
+ Clash.Promoted.Nat: predSNat :: SNat (a + 1) -> SNat a
+ Clash.Promoted.Nat: snatToNatural :: SNat n -> Natural
+ Clash.Promoted.Nat: succSNat :: SNat a -> SNat (a + 1)
+ Clash.Promoted.Symbol: instance GHC.TypeLits.KnownSymbol s => Language.Haskell.TH.Syntax.Lift (Clash.Promoted.Symbol.SSymbol s)
+ Clash.Signal: ActiveHigh :: ResetPolarity
+ Clash.Signal: ActiveLow :: ResetPolarity
+ Clash.Signal: Defined :: InitBehavior
+ Clash.Signal: DomainConfiguration :: Domain -> Nat -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> DomainConfiguration
+ Clash.Signal: Enable :: Signal dom Bool -> Enable dom
+ Clash.Signal: Falling :: ActiveEdge
+ Clash.Signal: Floating :: BiSignalDefault
+ Clash.Signal: PullDown :: BiSignalDefault
+ Clash.Signal: PullUp :: BiSignalDefault
+ Clash.Signal: Reset :: Signal dom Bool -> Reset (dom :: Domain)
+ Clash.Signal: Rising :: ActiveEdge
+ Clash.Signal: Unknown :: InitBehavior
+ Clash.Signal: VDomainConfiguration :: String -> Natural -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> VDomainConfiguration
+ Clash.Signal: [SActiveHigh] :: SResetPolarity 'ActiveHigh
+ Clash.Signal: [SActiveLow] :: SResetPolarity 'ActiveLow
+ Clash.Signal: [SAsynchronous] :: SResetKind 'Asynchronous
+ Clash.Signal: [SDefined] :: SInitBehavior 'Defined
+ Clash.Signal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Signal: [SFalling] :: SActiveEdge 'Falling
+ Clash.Signal: [SRising] :: SActiveEdge 'Rising
+ Clash.Signal: [SSynchronous] :: SResetKind 'Synchronous
+ Clash.Signal: [SUnknown] :: SInitBehavior 'Unknown
+ Clash.Signal: [_activeEdge] :: DomainConfiguration -> ActiveEdge
+ Clash.Signal: [_initBehavior] :: DomainConfiguration -> InitBehavior
+ Clash.Signal: [_name] :: DomainConfiguration -> Domain
+ Clash.Signal: [_period] :: DomainConfiguration -> Nat
+ Clash.Signal: [_resetKind] :: DomainConfiguration -> ResetKind
+ Clash.Signal: [_resetPolarity] :: DomainConfiguration -> ResetPolarity
+ Clash.Signal: [vActiveEdge] :: VDomainConfiguration -> ActiveEdge
+ Clash.Signal: [vInitBehavior] :: VDomainConfiguration -> InitBehavior
+ Clash.Signal: [vName] :: VDomainConfiguration -> String
+ Clash.Signal: [vPeriod] :: VDomainConfiguration -> Natural
+ Clash.Signal: [vResetKind] :: VDomainConfiguration -> ResetKind
+ Clash.Signal: [vResetPolarity] :: VDomainConfiguration -> ResetPolarity
+ Clash.Signal: activeEdge :: forall dom edge. (KnownDomain dom, DomainActiveEdge dom ~ edge) => SActiveEdge edge
+ Clash.Signal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Signal: clockPeriod :: forall dom period. (KnownDomain dom, DomainPeriod dom ~ period) => SNat period
+ Clash.Signal: createDomain :: VDomainConfiguration -> Q [Dec]
+ Clash.Signal: data ActiveEdge
+ Clash.Signal: data BiSignalDefault
+ Clash.Signal: data BiSignalIn (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)
+ Clash.Signal: data BiSignalOut (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)
+ Clash.Signal: data DomainConfiguration
+ Clash.Signal: data InitBehavior
+ Clash.Signal: data ResetPolarity
+ Clash.Signal: data SActiveEdge (edge :: ActiveEdge)
+ Clash.Signal: data SDomainConfiguration (dom :: Domain) (conf :: DomainConfiguration)
+ Clash.Signal: data SInitBehavior (init :: InitBehavior)
+ Clash.Signal: data SResetKind (resetKind :: ResetKind)
+ Clash.Signal: data SResetPolarity (polarity :: ResetPolarity)
+ Clash.Signal: data VDomainConfiguration
+ Clash.Signal: delayEn :: forall dom a. (NFDataX a, HiddenClock dom, HiddenEnable dom) => a -> Signal dom Bool -> Signal dom a -> Signal dom a
+ Clash.Signal: delayMaybe :: forall dom a. (NFDataX a, HiddenClock dom, HiddenEnable dom) => a -> Signal dom (Maybe a) -> Signal dom a
+ Clash.Signal: dflipflop :: forall dom a. (HiddenClock dom, NFDataX a) => Signal dom a -> Signal dom a
+ Clash.Signal: enableGen :: Enable dom
+ Clash.Signal: exposeClockResetEnable :: forall dom r. (HiddenClockResetEnable dom => r) -> KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r
+ Clash.Signal: exposeEnable :: forall dom r. (HiddenEnable dom => r) -> KnownDomain dom => Enable dom -> r
+ Clash.Signal: exposeSpecificClock :: forall dom r. WithSpecificDomain dom r => (HiddenClock dom => r) -> KnownDomain dom => Clock dom -> r
+ Clash.Signal: fromEnable :: Enable dom -> Signal dom Bool
+ Clash.Signal: fromListWithReset :: forall dom a. (HiddenReset dom, NFDataX a) => a -> [a] -> Signal dom a
+ Clash.Signal: hasEnable :: forall dom. HiddenEnable dom => Enable dom
+ Clash.Signal: hideClockResetEnable :: forall dom r. HiddenClockResetEnable dom => (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r) -> r
+ Clash.Signal: hideEnable :: forall dom r. HiddenEnable dom => (Enable dom -> r) -> r
+ Clash.Signal: holdReset :: forall dom m. HiddenClockResetEnable dom => SNat m -> Reset dom
+ Clash.Signal: hzToPeriod :: HasCallStack => Double -> Natural
+ Clash.Signal: initBehavior :: forall dom init. (KnownDomain dom, DomainInitBehavior dom ~ init) => SInitBehavior init
+ Clash.Signal: knownDomain :: KnownDomain dom => SDomainConfiguration dom (KnownConf dom)
+ Clash.Signal: knownVDomain :: forall dom. KnownDomain dom => VDomainConfiguration
+ Clash.Signal: mergeBiSignalOuts :: (HasCallStack, KnownNat n) => Vec n (BiSignalOut defaultState dom m) -> BiSignalOut defaultState dom m
+ Clash.Signal: newtype Enable dom
+ Clash.Signal: periodToHz :: Natural -> Double
+ Clash.Signal: readFromBiSignal :: (HasCallStack, KnownNat (BitSize a), BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d a
+ Clash.Signal: resetGen :: forall dom. KnownDomain dom => Reset dom
+ Clash.Signal: resetGenN :: forall dom n. (KnownDomain dom, 1 <= n) => SNat n -> Reset dom
+ Clash.Signal: resetKind :: forall dom sync. (KnownDomain dom, DomainResetKind dom ~ sync) => SResetKind sync
+ Clash.Signal: resetPolarity :: forall dom polarity. (KnownDomain dom, DomainResetPolarity dom ~ polarity) => SResetPolarity polarity
+ Clash.Signal: sampleWithReset :: forall dom a m. (KnownDomain dom, NFDataX a, 1 <= m) => SNat m -> (HiddenClockResetEnable dom => Signal dom a) -> [a]
+ Clash.Signal: sampleWithResetN :: forall dom a m. (KnownDomain dom, NFDataX a, 1 <= m) => SNat m -> Int -> (HiddenClockResetEnable dom => Signal dom a) -> [a]
+ Clash.Signal: simulateN :: forall dom a b. (KnownDomain dom, NFDataX a, NFDataX b) => Int -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b) -> [a] -> [b]
+ Clash.Signal: simulateWithReset :: forall dom a b m. (KnownDomain dom, NFDataX a, NFDataX b, 1 <= m) => SNat m -> a -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b) -> [a] -> [b]
+ Clash.Signal: simulateWithResetN :: forall dom a b m. (KnownDomain dom, NFDataX a, NFDataX b, 1 <= m) => SNat m -> a -> Int -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b) -> [a] -> [b]
+ Clash.Signal: toEnable :: Signal dom Bool -> Enable dom
+ Clash.Signal: type Domain = Symbol
+ Clash.Signal: type DomainActiveEdge (dom :: Domain) = DomainConfigurationActiveEdge (KnownConf dom)
+ Clash.Signal: type DomainInitBehavior (dom :: Domain) = DomainConfigurationInitBehavior (KnownConf dom)
+ Clash.Signal: type DomainPeriod (dom :: Domain) = DomainConfigurationPeriod (KnownConf dom)
+ Clash.Signal: type DomainResetKind (dom :: Domain) = DomainConfigurationResetKind (KnownConf dom)
+ Clash.Signal: type DomainResetPolarity (dom :: Domain) = DomainConfigurationResetPolarity (KnownConf dom)
+ Clash.Signal: type HiddenClockResetEnable dom = (HiddenClock dom, HiddenReset dom, HiddenEnable dom)
+ Clash.Signal: type HiddenEnable dom = (Hidden (HiddenEnableName dom) (Enable dom), KnownDomain dom)
+ Clash.Signal: type IntelSystem = ("IntelSystem" :: Domain)
+ Clash.Signal: type KnownConfiguration dom conf = (KnownDomain dom, KnownConf dom ~ conf)
+ Clash.Signal: type SystemClockResetEnable = (Hidden (HiddenClockName System) (Clock System), Hidden (HiddenResetName System) (Reset System), Hidden (HiddenEnableName System) (Enable System))
+ Clash.Signal: type XilinxSystem = ("XilinxSystem" :: Domain)
+ Clash.Signal: unsafeFromHighPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal: unsafeFromLowPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal: unsafeFromReset :: Reset dom -> Signal dom Bool
+ Clash.Signal: unsafeToHighPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal: unsafeToLowPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Signal: vDomain :: SDomainConfiguration dom conf -> VDomainConfiguration
+ Clash.Signal: vIntelSystem :: VDomainConfiguration
+ Clash.Signal: vSystem :: VDomainConfiguration
+ Clash.Signal: vXilinxSystem :: VDomainConfiguration
+ Clash.Signal: veryUnsafeToBiSignalIn :: (HasCallStack, KnownNat n, Given (SBiSignalDefault ds)) => BiSignalOut ds d n -> BiSignalIn ds d n
+ Clash.Signal: withClockResetEnable :: forall dom r. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> (HiddenClockResetEnable dom => r) -> r
+ Clash.Signal: withEnable :: forall dom r. KnownDomain dom => Enable dom -> (HiddenEnable dom => r) -> r
+ Clash.Signal: withSpecificClock :: forall dom r. (KnownDomain dom, WithSpecificDomain dom r) => Clock dom -> (HiddenClock dom => r) -> r
+ Clash.Signal: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Signal.BiSignal: Floating :: BiSignalDefault
+ Clash.Signal.BiSignal: PullDown :: BiSignalDefault
+ Clash.Signal.BiSignal: PullUp :: BiSignalDefault
+ Clash.Signal.BiSignal: data BiSignalDefault
+ Clash.Signal.BiSignal: data BiSignalIn (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)
+ Clash.Signal.BiSignal: data BiSignalOut (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)
+ Clash.Signal.BiSignal: instance Data.Reflection.Given (Clash.Signal.BiSignal.SBiSignalDefault 'Clash.Signal.BiSignal.Floating)
+ Clash.Signal.BiSignal: instance Data.Reflection.Given (Clash.Signal.BiSignal.SBiSignalDefault 'Clash.Signal.BiSignal.PullDown)
+ Clash.Signal.BiSignal: instance Data.Reflection.Given (Clash.Signal.BiSignal.SBiSignalDefault 'Clash.Signal.BiSignal.PullUp)
+ Clash.Signal.BiSignal: instance GHC.Base.Monoid (Clash.Signal.BiSignal.BiSignalOut defaultState dom n)
+ Clash.Signal.BiSignal: instance GHC.Base.Semigroup (Clash.Signal.BiSignal.BiSignalOut defaultState dom n)
+ Clash.Signal.BiSignal: instance GHC.Show.Show Clash.Signal.BiSignal.BiSignalDefault
+ Clash.Signal.BiSignal: mergeBiSignalOuts :: (HasCallStack, KnownNat n) => Vec n (BiSignalOut defaultState dom m) -> BiSignalOut defaultState dom m
+ Clash.Signal.BiSignal: readFromBiSignal :: (HasCallStack, KnownNat (BitSize a), BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d a
+ Clash.Signal.BiSignal: veryUnsafeToBiSignalIn :: (HasCallStack, KnownNat n, Given (SBiSignalDefault ds)) => BiSignalOut ds d n -> BiSignalIn ds d n
+ Clash.Signal.BiSignal: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Signal.Bundle: instance Clash.Signal.Bundle.Bundle (GHC.Maybe.Maybe a)
+ Clash.Signal.Delayed: delayI :: forall d n a dom. (HiddenClockResetEnable dom, NFDataX a, KnownNat d) => a -> DSignal dom n a -> DSignal dom (n + d) a
+ Clash.Signal.Delayed: delayN :: forall dom a d n. (HiddenClockResetEnable dom, NFDataX a) => SNat d -> a -> DSignal dom n a -> DSignal dom (n + d) a
+ Clash.Signal.Delayed: delayedFold :: forall dom n delay k a. (HiddenClockResetEnable dom, NFDataX a, KnownNat delay, KnownNat k) => SNat delay -> a -> (a -> a -> a) -> Vec (2 ^ k) (DSignal dom n a) -> DSignal dom (n + (delay * k)) a
+ Clash.Signal.Delayed.Bundle: bundle :: Bundle a => Unbundled dom d a -> DSignal dom d a
+ Clash.Signal.Delayed.Bundle: class Bundle a
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle ()
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Internal.Index.Index n)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Internal.Signed.Signed n)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Internal.Unsigned.Unsigned n)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (Data.Either.Either a b)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (GHC.Maybe.Maybe a)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c, d)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c, d, e)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c, d, e, f)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c, d, e, f, g)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle (a, b, c, d, e, f, g, h)
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle Clash.Sized.Internal.BitVector.Bit
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle GHC.Integer.Type.Integer
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle GHC.Types.Bool
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle GHC.Types.Double
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle GHC.Types.Float
+ Clash.Signal.Delayed.Bundle: instance Clash.Signal.Delayed.Bundle.Bundle GHC.Types.Int
+ Clash.Signal.Delayed.Bundle: instance GHC.TypeNats.KnownNat d => Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.RTree.RTree d a)
+ Clash.Signal.Delayed.Bundle: instance GHC.TypeNats.KnownNat n => Clash.Signal.Delayed.Bundle.Bundle (Clash.Sized.Vector.Vec n a)
+ Clash.Signal.Delayed.Bundle: type family Unbundled (dom :: Domain) (d :: Nat) a = res | res -> dom d a
+ Clash.Signal.Delayed.Bundle: unbundle :: Bundle a => DSignal dom d a -> Unbundled dom d a
+ Clash.Signal.Delayed.Internal: DSignal :: Signal dom a -> DSignal (dom :: Domain) (delay :: Nat) a
+ Clash.Signal.Delayed.Internal: [toSignal] :: DSignal (dom :: Domain) (delay :: Nat) a -> Signal dom a
+ Clash.Signal.Delayed.Internal: antiDelay :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a
+ Clash.Signal.Delayed.Internal: dfromList :: NFDataX a => [a] -> DSignal dom 0 a
+ Clash.Signal.Delayed.Internal: dfromList_lazy :: [a] -> DSignal dom 0 a
+ Clash.Signal.Delayed.Internal: feedback :: (DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)) -> DSignal dom n a
+ Clash.Signal.Delayed.Internal: fromSignal :: Signal dom a -> DSignal dom 0 a
+ Clash.Signal.Delayed.Internal: instance Data.Default.Class.Default a => Data.Default.Class.Default (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance Data.Foldable.Foldable (Clash.Signal.Delayed.Internal.DSignal dom delay)
+ Clash.Signal.Delayed.Internal: instance Data.Traversable.Traversable (Clash.Signal.Delayed.Internal.DSignal dom delay)
+ Clash.Signal.Delayed.Internal: instance GHC.Base.Applicative (Clash.Signal.Delayed.Internal.DSignal dom delay)
+ Clash.Signal.Delayed.Internal: instance GHC.Base.Functor (Clash.Signal.Delayed.Internal.DSignal dom delay)
+ Clash.Signal.Delayed.Internal: instance GHC.Num.Num a => GHC.Num.Num (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance GHC.Real.Fractional a => GHC.Real.Fractional (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance GHC.Show.Show a => GHC.Show.Show (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance Language.Haskell.TH.Syntax.Lift a => Language.Haskell.TH.Syntax.Lift (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: instance Test.QuickCheck.Arbitrary.CoArbitrary a => Test.QuickCheck.Arbitrary.CoArbitrary (Clash.Signal.Delayed.Internal.DSignal dom delay a)
+ Clash.Signal.Delayed.Internal: newtype DSignal (dom :: Domain) (delay :: Nat) a
+ Clash.Signal.Delayed.Internal: unsafeFromSignal :: Signal dom a -> DSignal dom n a
+ Clash.Signal.Internal: ActiveHigh :: ResetPolarity
+ Clash.Signal.Internal: ActiveLow :: ResetPolarity
+ Clash.Signal.Internal: Clock :: SSymbol dom -> Clock (dom :: Domain)
+ Clash.Signal.Internal: Defined :: InitBehavior
+ Clash.Signal.Internal: DomainConfiguration :: Domain -> Nat -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> DomainConfiguration
+ Clash.Signal.Internal: Enable :: Signal dom Bool -> Enable dom
+ Clash.Signal.Internal: Falling :: ActiveEdge
+ Clash.Signal.Internal: Reset :: Signal dom Bool -> Reset (dom :: Domain)
+ Clash.Signal.Internal: Rising :: ActiveEdge
+ Clash.Signal.Internal: Unknown :: InitBehavior
+ Clash.Signal.Internal: VDomainConfiguration :: String -> Natural -> ActiveEdge -> ResetKind -> InitBehavior -> ResetPolarity -> VDomainConfiguration
+ Clash.Signal.Internal: [SActiveHigh] :: SResetPolarity 'ActiveHigh
+ Clash.Signal.Internal: [SActiveLow] :: SResetPolarity 'ActiveLow
+ Clash.Signal.Internal: [SAsynchronous] :: SResetKind 'Asynchronous
+ Clash.Signal.Internal: [SDefined] :: SInitBehavior 'Defined
+ Clash.Signal.Internal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Signal.Internal: [SFalling] :: SActiveEdge 'Falling
+ Clash.Signal.Internal: [SRising] :: SActiveEdge 'Rising
+ Clash.Signal.Internal: [SSynchronous] :: SResetKind 'Synchronous
+ Clash.Signal.Internal: [SUnknown] :: SInitBehavior 'Unknown
+ Clash.Signal.Internal: [_activeEdge] :: DomainConfiguration -> ActiveEdge
+ Clash.Signal.Internal: [_initBehavior] :: DomainConfiguration -> InitBehavior
+ Clash.Signal.Internal: [_name] :: DomainConfiguration -> Domain
+ Clash.Signal.Internal: [_period] :: DomainConfiguration -> Nat
+ Clash.Signal.Internal: [_resetKind] :: DomainConfiguration -> ResetKind
+ Clash.Signal.Internal: [_resetPolarity] :: DomainConfiguration -> ResetPolarity
+ Clash.Signal.Internal: [vActiveEdge] :: VDomainConfiguration -> ActiveEdge
+ Clash.Signal.Internal: [vInitBehavior] :: VDomainConfiguration -> InitBehavior
+ Clash.Signal.Internal: [vName] :: VDomainConfiguration -> String
+ Clash.Signal.Internal: [vPeriod] :: VDomainConfiguration -> Natural
+ Clash.Signal.Internal: [vResetKind] :: VDomainConfiguration -> ResetKind
+ Clash.Signal.Internal: [vResetPolarity] :: VDomainConfiguration -> ResetPolarity
+ Clash.Signal.Internal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Signal.Internal: clockTag :: Clock dom -> SSymbol dom
+ Clash.Signal.Internal: createDomain :: VDomainConfiguration -> Q [Dec]
+ Clash.Signal.Internal: data ActiveEdge
+ Clash.Signal.Internal: data DomainConfiguration
+ Clash.Signal.Internal: data InitBehavior
+ Clash.Signal.Internal: data ResetPolarity
+ Clash.Signal.Internal: data SActiveEdge (edge :: ActiveEdge)
+ Clash.Signal.Internal: data SDomainConfiguration (dom :: Domain) (conf :: DomainConfiguration)
+ Clash.Signal.Internal: data SInitBehavior (init :: InitBehavior)
+ Clash.Signal.Internal: data SResetKind (resetKind :: ResetKind)
+ Clash.Signal.Internal: data SResetPolarity (polarity :: ResetPolarity)
+ Clash.Signal.Internal: data VDomainConfiguration
+ Clash.Signal.Internal: enableGen :: Enable dom
+ Clash.Signal.Internal: fromEnable :: Enable dom -> Signal dom Bool
+ Clash.Signal.Internal: head# :: Signal dom a -> a
+ Clash.Signal.Internal: hzToPeriod :: HasCallStack => Double -> Natural
+ Clash.Signal.Internal: infixr 5 :-
+ Clash.Signal.Internal: instance Clash.Signal.Internal.KnownDomain Clash.Signal.Internal.IntelSystem
+ Clash.Signal.Internal: instance Clash.Signal.Internal.KnownDomain Clash.Signal.Internal.System
+ Clash.Signal.Internal: instance Clash.Signal.Internal.KnownDomain Clash.Signal.Internal.XilinxSystem
+ Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance Data.Binary.Class.Binary Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance Data.Data.Data Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance Data.Data.Data Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance Data.Data.Data Clash.Signal.Internal.ResetKind
+ Clash.Signal.Internal: instance Data.Data.Data Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance Data.Default.Class.Default a => Data.Default.Class.Default (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance Data.Foldable.Foldable (Clash.Signal.Internal.Signal dom)
+ Clash.Signal.Internal: instance Data.Hashable.Class.Hashable Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance Data.Hashable.Class.Hashable Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance Data.Hashable.Class.Hashable Clash.Signal.Internal.ResetKind
+ Clash.Signal.Internal: instance Data.Hashable.Class.Hashable Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance Data.Traversable.Traversable (Clash.Signal.Internal.Signal dom)
+ Clash.Signal.Internal: instance GHC.Base.Applicative (Clash.Signal.Internal.Signal dom)
+ Clash.Signal.Internal: instance GHC.Base.Functor (Clash.Signal.Internal.Signal dom)
+ Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance GHC.Classes.Ord Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance GHC.Classes.Ord Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance GHC.Classes.Ord Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance GHC.Num.Num a => GHC.Num.Num (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance GHC.Real.Fractional a => GHC.Real.Fractional (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.Clock dom)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.SActiveEdge edge)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.SDomainConfiguration dom conf)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.SInitBehavior init)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.SResetKind reset)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.SResetPolarity polarity)
+ Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.ActiveEdge
+ Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance GHC.Show.Show a => GHC.Show.Show (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance Language.Haskell.TH.Syntax.Lift a => Language.Haskell.TH.Syntax.Lift (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: instance Test.QuickCheck.Arbitrary.CoArbitrary a => Test.QuickCheck.Arbitrary.CoArbitrary (Clash.Signal.Internal.Signal dom a)
+ Clash.Signal.Internal: invertReset :: Reset dom -> Reset dom
+ Clash.Signal.Internal: knownDomain :: KnownDomain dom => SDomainConfiguration dom (KnownConf dom)
+ Clash.Signal.Internal: knownDomainByName :: forall dom. KnownDomain dom => SSymbol dom -> SDomainConfiguration dom (KnownConf dom)
+ Clash.Signal.Internal: newtype Enable dom
+ Clash.Signal.Internal: periodToHz :: Natural -> Double
+ Clash.Signal.Internal: resetGen :: forall dom. KnownDomain dom => Reset dom
+ Clash.Signal.Internal: resetGenN :: forall dom n. (KnownDomain dom, 1 <= n) => SNat n -> Reset dom
+ Clash.Signal.Internal: tail# :: Signal dom a -> Signal dom a
+ Clash.Signal.Internal: toEnable :: Signal dom Bool -> Enable dom
+ Clash.Signal.Internal: type Domain = Symbol
+ Clash.Signal.Internal: type DomainActiveEdge (dom :: Domain) = DomainConfigurationActiveEdge (KnownConf dom)
+ Clash.Signal.Internal: type DomainInitBehavior (dom :: Domain) = DomainConfigurationInitBehavior (KnownConf dom)
+ Clash.Signal.Internal: type DomainPeriod (dom :: Domain) = DomainConfigurationPeriod (KnownConf dom)
+ Clash.Signal.Internal: type DomainResetKind (dom :: Domain) = DomainConfigurationResetKind (KnownConf dom)
+ Clash.Signal.Internal: type DomainResetPolarity (dom :: Domain) = DomainConfigurationResetPolarity (KnownConf dom)
+ Clash.Signal.Internal: type IntelSystem = ("IntelSystem" :: Domain)
+ Clash.Signal.Internal: type KnownConfiguration dom conf = (KnownDomain dom, KnownConf dom ~ conf)
+ Clash.Signal.Internal: type System = ("System" :: Domain)
+ Clash.Signal.Internal: type XilinxSystem = ("XilinxSystem" :: Domain)
+ Clash.Signal.Internal: type family KnownConf dom :: DomainConfiguration;
+ Clash.Signal.Internal: unsafeFromHighPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: unsafeFromLowPolarity :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: unsafeFromReset :: Reset dom -> Signal dom Bool
+ Clash.Signal.Internal: unsafeToHighPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal.Internal: unsafeToLowPolarity :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal.Internal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: vDomain :: SDomainConfiguration dom conf -> VDomainConfiguration
+ Clash.Signal.Internal: vIntelSystem :: VDomainConfiguration
+ Clash.Signal.Internal: vSystem :: VDomainConfiguration
+ Clash.Signal.Internal: vXilinxSystem :: VDomainConfiguration
+ Clash.Signal.Internal: }
+ Clash.Signal.Internal.Ambiguous: activeEdge :: forall dom edge. (KnownDomain dom, DomainActiveEdge dom ~ edge) => SActiveEdge edge
+ Clash.Signal.Internal.Ambiguous: clockPeriod :: forall dom period. (KnownDomain dom, DomainPeriod dom ~ period) => SNat period
+ Clash.Signal.Internal.Ambiguous: initBehavior :: forall dom init. (KnownDomain dom, DomainInitBehavior dom ~ init) => SInitBehavior init
+ Clash.Signal.Internal.Ambiguous: knownVDomain :: forall dom. KnownDomain dom => VDomainConfiguration
+ Clash.Signal.Internal.Ambiguous: resetKind :: forall dom sync. (KnownDomain dom, DomainResetKind dom ~ sync) => SResetKind sync
+ Clash.Signal.Internal.Ambiguous: resetPolarity :: forall dom polarity. (KnownDomain dom, DomainResetPolarity dom ~ polarity) => SResetPolarity polarity
+ Clash.Signal.Trace: dumpReplayable :: forall a dom. NFDataX a => Int -> Signal dom a -> String -> IO ByteString
+ Clash.Signal.Trace: dumpVCD :: NFDataX a => (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
+ Clash.Signal.Trace: dumpVCD# :: NFDataX a => IORef TraceMap -> (Int, Int) -> Signal dom a -> [String] -> IO (Either String Text)
+ Clash.Signal.Trace: dumpVCD## :: (Int, Int) -> TraceMap -> UTCTime -> Either String Text
+ Clash.Signal.Trace: replay :: forall a dom n. (Typeable a, NFDataX a, BitPack a, KnownNat n, n ~ BitSize a) => ByteString -> Either String (Signal dom a)
+ Clash.Signal.Trace: traceMap# :: IORef TraceMap
+ Clash.Signal.Trace: traceSignal :: forall dom a. (KnownDomain dom, KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Signal.Trace: traceSignal# :: forall dom a. (KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => IORef TraceMap -> Int -> String -> Signal dom a -> IO (Signal dom a)
+ Clash.Signal.Trace: traceSignal1 :: (KnownNat (BitSize a), BitPack a, NFDataX a, Typeable a) => String -> Signal dom a -> Signal dom a
+ Clash.Signal.Trace: traceVecSignal :: forall dom a n. (KnownDomain dom, KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Signal.Trace: traceVecSignal# :: forall dom n a. (KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => IORef TraceMap -> Int -> String -> Signal dom (Vec (n + 1) a) -> IO (Signal dom (Vec (n + 1) a))
+ Clash.Signal.Trace: traceVecSignal1 :: (KnownNat (BitSize a), KnownNat n, BitPack a, NFDataX a, Typeable a) => String -> Signal dom (Vec (n + 1) a) -> Signal dom (Vec (n + 1) a)
+ Clash.Signal.Trace: type Changed = Bool
+ Clash.Signal.Trace: type Period = Int
+ Clash.Signal.Trace: type TraceMap = Map String (TypeRepBS, Period, Width, [Value])
+ Clash.Signal.Trace: type Value = (Integer, Integer)
+ Clash.Signal.Trace: type Width = Int
+ Clash.Signal.Trace: waitForTraces# :: NFDataX a => IORef TraceMap -> Signal dom a -> [String] -> IO ()
+ Clash.Sized.BitVector: bitPattern :: String -> Q Pat
+ Clash.Sized.Fixed: instance (Clash.Sized.Fixed.FracFixedC rep int frac, Clash.Sized.Fixed.NumFixedC rep int frac, GHC.Real.Integral (rep (int GHC.TypeNats.+ frac))) => GHC.Real.RealFrac (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Fixed: instance (size GHC.Types.~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Enum.Bounded (rep size), GHC.Real.Integral (rep size)) => GHC.Read.Read (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Fixed: instance (size GHC.Types.~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Real.Integral (rep size)) => Clash.XException.ShowX (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Fixed: instance (size GHC.Types.~ (int GHC.TypeNats.+ frac), GHC.TypeNats.KnownNat frac, GHC.Real.Integral (rep size)) => GHC.Show.Show (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Fixed: instance Clash.XException.NFDataX (rep (int GHC.TypeNats.+ frac)) => Clash.XException.NFDataX (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Internal.BitVector: [unsafeMask#] :: Bit -> !Integer
+ Clash.Sized.Internal.BitVector: [unsafeMask] :: BitVector (n :: Nat) -> !Integer
+ Clash.Sized.Internal.BitVector: bitPattern :: String -> Q Pat
+ Clash.Sized.Internal.BitVector: checkUnpackUndef :: (KnownNat n, Typeable a) => (BitVector n -> a) -> BitVector n -> a
+ Clash.Sized.Internal.BitVector: data Bit
+ Clash.Sized.Internal.BitVector: data BitVector (n :: Nat)
+ Clash.Sized.Internal.BitVector: instance Clash.XException.NFDataX (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Sized.Internal.BitVector: instance Clash.XException.NFDataX Clash.Sized.Internal.BitVector.Bit
+ Clash.Sized.Internal.BitVector: instance GHC.Generics.Generic (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Sized.Internal.BitVector: instance GHC.Generics.Generic Clash.Sized.Internal.BitVector.Bit
+ Clash.Sized.Internal.BitVector: instance GHC.TypeNats.KnownNat n => GHC.Classes.Eq (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Sized.Internal.BitVector: instance GHC.TypeNats.KnownNat n => GHC.Classes.Ord (Clash.Sized.Internal.BitVector.BitVector n)
+ Clash.Sized.Internal.BitVector: isLike :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: truncateB# :: forall a b. KnownNat a => BitVector (a + b) -> BitVector a
+ Clash.Sized.Internal.BitVector: undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a
+ Clash.Sized.Internal.BitVector: undefined# :: forall n. KnownNat n => BitVector n
+ Clash.Sized.Internal.Index: instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Clash.Class.BitPack.BitPack (Clash.Sized.Internal.Index.Index n)
+ Clash.Sized.Internal.Index: instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Bits.Bits (Clash.Sized.Internal.Index.Index n)
+ Clash.Sized.Internal.Index: instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Bits.FiniteBits (Clash.Sized.Internal.Index.Index n)
+ Clash.Sized.Internal.Index: instance Clash.XException.NFDataX (Clash.Sized.Internal.Index.Index n)
+ Clash.Sized.Internal.Index: instance GHC.Generics.Generic (Clash.Sized.Internal.Index.Index n)
+ Clash.Sized.Internal.Index: size# :: (KnownNat n, 1 <= n) => Index n -> Int
+ Clash.Sized.Internal.Signed: instance Clash.XException.NFDataX (Clash.Sized.Internal.Signed.Signed n)
+ Clash.Sized.Internal.Signed: instance GHC.Generics.Generic (Clash.Sized.Internal.Signed.Signed n)
+ Clash.Sized.Internal.Unsigned: instance Clash.XException.NFDataX (Clash.Sized.Internal.Unsigned.Unsigned n)
+ Clash.Sized.Internal.Unsigned: instance GHC.Generics.Generic (Clash.Sized.Internal.Unsigned.Unsigned n)
+ Clash.Sized.Internal.Unsigned: instance GHC.TypeNats.KnownNat n => Clash.Class.BitPack.BitPack (Clash.Sized.Internal.Unsigned.Unsigned n)
+ Clash.Sized.RTree: instance (GHC.TypeNats.KnownNat d, Clash.XException.NFDataX a) => Clash.XException.NFDataX (Clash.Sized.RTree.RTree d a)
+ Clash.Sized.RTree: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Clash.Sized.RTree.RTree d a)
+ Clash.Sized.RTree: pattern BR :: RTree d a -> RTree d a -> RTree (d + 1) a
+ Clash.Sized.RTree: pattern LR :: a -> RTree 0 a
+ Clash.Sized.Vector: [Cons] :: a -> Vec n a -> Vec (n + 1) a
+ Clash.Sized.Vector: concatMap :: (a -> Vec m b) -> Vec n a -> Vec (n * m) b
+ Clash.Sized.Vector: forceV :: KnownNat n => Vec n a -> Vec n a
+ Clash.Sized.Vector: forceVX :: KnownNat n => Vec n a -> Vec n a
+ Clash.Sized.Vector: infixl 5 :<
+ Clash.Sized.Vector: infixr 0 `seqVX`
+ Clash.Sized.Vector: instance (Clash.XException.NFDataX a, GHC.TypeNats.KnownNat n) => Clash.XException.NFDataX (Clash.Sized.Vector.Vec n a)
+ Clash.Sized.Vector: instance (GHC.TypeNats.KnownNat n, Data.Typeable.Internal.Typeable a, Data.Data.Data a) => Data.Data.Data (Clash.Sized.Vector.Vec n a)
+ Clash.Sized.Vector: instance GHC.TypeNats.KnownNat n => GHC.Generics.Generic (Clash.Sized.Vector.Vec n a)
+ Clash.Sized.Vector: pattern (:<) :: Vec n a -> a -> Vec (n + 1) a
+ Clash.Sized.Vector: seqV :: KnownNat n => Vec n a -> b -> b
+ Clash.Sized.Vector: seqVX :: KnownNat n => Vec n a -> b -> b
+ Clash.Sized.Vector: unzip4 :: Vec n (a, b, c, d) -> (Vec n a, Vec n b, Vec n c, Vec n d)
+ Clash.Sized.Vector: unzip5 :: Vec n (a, b, c, d, e) -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e)
+ Clash.Sized.Vector: unzip6 :: Vec n (a, b, c, d, e, f) -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e, Vec n f)
+ Clash.Sized.Vector: unzip7 :: Vec n (a, b, c, d, e, f, g) -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e, Vec n f, Vec n g)
+ Clash.Sized.Vector: zip4 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n (a, b, c, d)
+ Clash.Sized.Vector: zip5 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n (a, b, c, d, e)
+ Clash.Sized.Vector: zip6 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n f -> Vec n (a, b, c, d, e, f)
+ Clash.Sized.Vector: zip7 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n f -> Vec n g -> Vec n (a, b, c, d, e, f, g)
+ Clash.Sized.Vector: zipWith4 :: (a -> b -> c -> d -> e) -> Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e
+ Clash.Sized.Vector: zipWith5 :: (a -> b -> c -> d -> e -> f) -> Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n f
+ Clash.Sized.Vector: zipWith6 :: (a -> b -> c -> d -> e -> f -> g) -> Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n f -> Vec n g
+ Clash.Sized.Vector: zipWith7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n f -> Vec n g -> Vec n h
+ Clash.XException: XException :: String -> XException
+ Clash.XException: class NFDataX a
+ Clash.XException: deepErrorX :: (NFDataX a, HasCallStack, Generic a, GDeepErrorX (Rep a)) => String -> a
+ Clash.XException: deepseqX :: NFDataX a => a -> b -> b
+ Clash.XException: defaultSeqX :: NFDataX a => a -> b -> b
+ Clash.XException: forceX :: NFDataX a => a -> a
+ Clash.XException: hasX :: NFData a => a -> Either String a
+ Clash.XException: instance (Clash.XException.GDeepErrorX f, Clash.XException.GDeepErrorX g) => Clash.XException.GDeepErrorX (f GHC.Generics.:*: g)
+ Clash.XException: instance (Clash.XException.GNFDataX arity a, Clash.XException.GNFDataX arity b) => Clash.XException.GNFDataX arity (a GHC.Generics.:*: b)
+ Clash.XException: instance (Clash.XException.GNFDataX arity a, Clash.XException.GNFDataX arity b) => Clash.XException.GNFDataX arity (a GHC.Generics.:+: b)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b) => Clash.XException.NFDataX (Data.Either.Either a b)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b) => Clash.XException.NFDataX (Data.Semigroup.Arg a b)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b) => Clash.XException.NFDataX (a, b)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c) => Clash.XException.NFDataX (a, b, c)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d) => Clash.XException.NFDataX (a, b, c, d)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e) => Clash.XException.NFDataX (a, b, c, d, e)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f) => Clash.XException.NFDataX (a, b, c, d, e, f)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g) => Clash.XException.NFDataX (a, b, c, d, e, f, g)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j, Clash.XException.NFDataX k) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j, k)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j, Clash.XException.NFDataX k, Clash.XException.NFDataX l) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j, k, l)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j, Clash.XException.NFDataX k, Clash.XException.NFDataX l, Clash.XException.NFDataX m) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j, k, l, m)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j, Clash.XException.NFDataX k, Clash.XException.NFDataX l, Clash.XException.NFDataX m, Clash.XException.NFDataX n) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
+ Clash.XException: instance (Clash.XException.NFDataX a, Clash.XException.NFDataX b, Clash.XException.NFDataX c, Clash.XException.NFDataX d, Clash.XException.NFDataX e, Clash.XException.NFDataX f, Clash.XException.NFDataX g, Clash.XException.NFDataX h, Clash.XException.NFDataX i, Clash.XException.NFDataX j, Clash.XException.NFDataX k, Clash.XException.NFDataX l, Clash.XException.NFDataX m, Clash.XException.NFDataX n, Clash.XException.NFDataX o) => Clash.XException.NFDataX (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+ Clash.XException: instance (Clash.XException.NFDataX1 f, Clash.XException.GNFDataX Clash.XException.One g) => Clash.XException.GNFDataX Clash.XException.One (f GHC.Generics.:.: g)
+ Clash.XException: instance Clash.XException.GDeepErrorX (f GHC.Generics.:+: g)
+ Clash.XException: instance Clash.XException.GDeepErrorX GHC.Generics.U1
+ Clash.XException: instance Clash.XException.GDeepErrorX GHC.Generics.V1
+ Clash.XException: instance Clash.XException.GDeepErrorX a => Clash.XException.GDeepErrorX (GHC.Generics.M1 m d a)
+ Clash.XException: instance Clash.XException.GNFDataX Clash.XException.One GHC.Generics.Par1
+ Clash.XException: instance Clash.XException.GNFDataX arity GHC.Generics.U1
+ Clash.XException: instance Clash.XException.GNFDataX arity GHC.Generics.V1
+ Clash.XException: instance Clash.XException.GNFDataX arity a => Clash.XException.GNFDataX arity (GHC.Generics.M1 i c a)
+ Clash.XException: instance Clash.XException.NFDataX ()
+ Clash.XException: instance Clash.XException.NFDataX Data.Semigroup.Internal.All
+ Clash.XException: instance Clash.XException.NFDataX Data.Semigroup.Internal.Any
+ Clash.XException: instance Clash.XException.NFDataX GHC.Int.Int16
+ Clash.XException: instance Clash.XException.NFDataX GHC.Int.Int32
+ Clash.XException: instance Clash.XException.NFDataX GHC.Int.Int64
+ Clash.XException: instance Clash.XException.NFDataX GHC.Int.Int8
+ Clash.XException: instance Clash.XException.NFDataX GHC.Integer.Type.Integer
+ Clash.XException: instance Clash.XException.NFDataX GHC.Natural.Natural
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Bool
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Char
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Double
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Float
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Int
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Word
+ Clash.XException: instance Clash.XException.NFDataX GHC.Word.Word16
+ Clash.XException: instance Clash.XException.NFDataX GHC.Word.Word32
+ Clash.XException: instance Clash.XException.NFDataX GHC.Word.Word64
+ Clash.XException: instance Clash.XException.NFDataX GHC.Word.Word8
+ Clash.XException: instance Clash.XException.NFDataX Numeric.Half.Half
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.GNFDataX arity (GHC.Generics.K1 i a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Complex.Complex a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Ord.Down a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.First a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Internal.Dual a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Internal.Endo a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Internal.Product a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Internal.Sum a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Last a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Max a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Min a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Semigroup.Option a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Sequence.Internal.Seq a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (GHC.Maybe.Maybe a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (GHC.Real.Ratio a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX [a]
+ Clash.XException: instance Clash.XException.NFDataX b => Clash.XException.NFDataX (a -> b)
+ Clash.XException: instance Clash.XException.NFDataX c => Clash.XException.GDeepErrorX (GHC.Generics.K1 i c)
+ Clash.XException: instance Clash.XException.NFDataX1 f => Clash.XException.GNFDataX Clash.XException.One (GHC.Generics.Rec1 f)
+ Clash.XException: instance Clash.XException.ShowX GHC.Natural.Natural
+ Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (Data.Ord.Down a)
+ Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (Data.Sequence.Internal.Seq a)
+ Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (GHC.Maybe.Maybe a)
+ Clash.XException: instance GHC.Exception.Type.Exception Clash.XException.XException
+ Clash.XException: maybeHasX :: NFData a => a -> Maybe a
+ Clash.XException: maybeIsX :: NFData a => a -> Maybe a
+ Clash.XException: newtype XException
+ Clash.XException: rnfX :: (NFDataX a, Generic a, GNFDataX Zero (Rep a)) => a -> ()
+ Clash.XException: rwhnfX :: a -> ()
- Clash.Class.BitPack: pack :: (BitPack a, Generic a, GBitPack (Rep a), GBitSize (Rep a) ~ BitSize a) => a -> BitVector (BitSize a)
+ Clash.Class.BitPack: pack :: (BitPack a, Generic a, GBitPack (Rep a), KnownNat (BitSize a), KnownNat constrSize, KnownNat fieldSize, constrSize ~ CLog 2 (GConstructorCount (Rep a)), fieldSize ~ GFieldSize (Rep a), (constrSize + fieldSize) ~ BitSize a) => a -> BitVector (BitSize a)
- Clash.Class.BitPack: type BitSize a = GBitSize (Rep a);
+ Clash.Class.BitPack: type BitSize a = (CLog 2 (GConstructorCount (Rep a))) + (GFieldSize (Rep a));
- Clash.Class.BitPack: unpack :: (BitPack a, Generic a, GBitPack (Rep a), GBitSize (Rep a) ~ BitSize a) => BitVector (BitSize a) -> a
+ Clash.Class.BitPack: unpack :: (BitPack a, Generic a, GBitPack (Rep a), KnownNat constrSize, KnownNat fieldSize, constrSize ~ CLog 2 (GConstructorCount (Rep a)), fieldSize ~ GFieldSize (Rep a), (constrSize + fieldSize) ~ BitSize a) => BitVector (BitSize a) -> a
- Clash.Explicit.BlockRam: blockRam :: HasCallStack => Enum addr => Clock dom gated -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.BlockRam: blockRam# :: HasCallStack => Clock dom gated -> Vec n a -> Signal dom Int -> Signal dom Bool -> Signal dom Int -> Signal dom a -> Signal dom a
+ Clash.Explicit.BlockRam: blockRam# :: (KnownDomain dom, HasCallStack, NFDataX a) => Clock dom -> Enable dom -> Vec n a -> Signal dom Int -> Signal dom Bool -> Signal dom Int -> Signal dom a -> Signal dom a
- Clash.Explicit.BlockRam: blockRamPow2 :: (KnownNat n, HasCallStack) => Clock dom gated -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRamPow2 :: (KnownDomain dom, HasCallStack, NFDataX a, KnownNat n) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Explicit.BlockRam: readNew :: Eq addr => Reset domain synchronous -> Clock domain gated -> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Explicit.BlockRam: readNew :: (KnownDomain dom, NFDataX a, Eq addr) => Clock dom -> Reset dom -> Enable dom -> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.BlockRam.File: blockRamFile :: (KnownNat m, Enum addr, HasCallStack) => Clock dom gated -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.BlockRam.File: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.BlockRam.File: blockRamFile# :: (KnownNat m, HasCallStack) => Clock dom gated -> SNat n -> FilePath -> Signal dom Int -> Signal dom Bool -> Signal dom Int -> Signal dom (BitVector m) -> Signal dom (BitVector m)
+ Clash.Explicit.BlockRam.File: blockRamFile# :: forall m dom n. (KnownDomain dom, KnownNat m, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom Int -> Signal dom Bool -> Signal dom Int -> Signal dom (BitVector m) -> Signal dom (BitVector m)
- Clash.Explicit.BlockRam.File: blockRamFilePow2 :: forall dom gated n m. (KnownNat m, KnownNat n, HasCallStack) => Clock dom gated -> FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.BlockRam.File: blockRamFilePow2 :: forall dom n m. (KnownDomain dom, KnownNat m, KnownNat n, HasCallStack) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.DDR: ddrIn :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast)) => Clock slow gated -> Reset slow synchronous -> (a, a, a) -> Signal fast a -> Signal slow (a, a)
+ Clash.Explicit.DDR: ddrIn :: (HasCallStack, NFDataX a, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity)) => Clock slow -> Reset slow -> Enable slow -> (a, a, a) -> Signal fast a -> Signal slow (a, a)
- Clash.Explicit.DDR: ddrIn# :: forall a slow fast n pFast gated synchronous. (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast)) => Clock slow gated -> Reset slow synchronous -> a -> a -> a -> Signal fast a -> Signal slow (a, a)
+ Clash.Explicit.DDR: ddrIn# :: forall a slow fast fPeriod polarity edge reset init. (HasCallStack, NFDataX a, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity)) => Clock slow -> Reset slow -> Enable slow -> a -> a -> a -> Signal fast a -> Signal slow (a, a)
- Clash.Explicit.DDR: ddrOut :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast)) => Clock slow gated -> Reset slow synchronous -> a -> Signal slow (a, a) -> Signal fast a
+ Clash.Explicit.DDR: ddrOut :: (HasCallStack, NFDataX a, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity)) => Clock slow -> Reset slow -> Enable slow -> a -> Signal slow (a, a) -> Signal fast a
- Clash.Explicit.DDR: ddrOut# :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast)) => Clock slow gated -> Reset slow synchronous -> a -> Signal slow a -> Signal slow a -> Signal fast a
+ Clash.Explicit.DDR: ddrOut# :: (HasCallStack, NFDataX a, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity)) => Clock slow -> Reset slow -> Enable slow -> a -> Signal slow a -> Signal slow a -> Signal fast a
- Clash.Explicit.Mealy: mealy :: Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Signal dom i -> Signal dom o)
+ Clash.Explicit.Mealy: mealy :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Mealy: mealyB :: (Bundle i, Bundle o) => Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Unbundled dom i -> Unbundled dom o)
+ Clash.Explicit.Mealy: mealyB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Moore: medvedev :: Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> s -> (Signal domain i -> Signal domain s)
+ Clash.Explicit.Moore: medvedev :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> s -> Signal dom i -> Signal dom s
- Clash.Explicit.Moore: medvedevB :: (Bundle i, Bundle s) => Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> s -> (Unbundled domain i -> Unbundled domain s)
+ Clash.Explicit.Moore: medvedevB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> s -> Unbundled dom i -> Unbundled dom s
- Clash.Explicit.Moore: moore :: Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Explicit.Moore: moore :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Moore: mooreB :: (Bundle i, Bundle o) => Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Explicit.Moore: mooreB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Prelude: assert :: (Eq a, ShowX a) => Clock domain gated -> Reset domain synchronous -> String -> Signal domain a -> Signal domain a -> Signal domain b -> Signal domain b
+ Clash.Explicit.Prelude: assert :: (KnownDomain dom, Eq a, ShowX a) => Clock dom -> Reset dom -> String -> Signal dom a -> Signal dom a -> Signal dom b -> Signal dom b
- Clash.Explicit.Prelude: asyncFIFOSynchronizer :: (2 <= addrSize) => SNat addrSize -> Clock wdomain wgated -> Clock rdomain rgated -> Reset wdomain synchronous -> Reset rdomain synchronous -> Signal rdomain Bool -> Signal wdomain (Maybe a) -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)
+ Clash.Explicit.Prelude: asyncFIFOSynchronizer :: (KnownDomain wdom, KnownDomain rdom, 2 <= addrSize) => SNat addrSize -> Clock wdom -> Clock rdom -> Reset wdom -> Reset rdom -> Enable wdom -> Enable rdom -> Signal rdom Bool -> Signal wdom (Maybe a) -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)
- Clash.Explicit.Prelude: asyncRam :: (Enum addr, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.Prelude: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.Prelude: asyncRamPow2 :: forall wdom rdom wgated rgated n a. (KnownNat n, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
+ Clash.Explicit.Prelude: asyncRamPow2 :: forall wdom rdom n a. (KnownNat n, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
- Clash.Explicit.Prelude: blockRam :: HasCallStack => Enum addr => Clock dom gated -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude: blockRamFile :: (KnownNat m, Enum addr, HasCallStack) => Clock dom gated -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.Prelude: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: blockRamFilePow2 :: forall dom gated n m. (KnownNat m, KnownNat n, HasCallStack) => Clock dom gated -> FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.Prelude: blockRamFilePow2 :: forall dom n m. (KnownDomain dom, KnownNat m, KnownNat n, HasCallStack) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: blockRamPow2 :: (KnownNat n, HasCallStack) => Clock dom gated -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRamPow2 :: (KnownDomain dom, HasCallStack, NFDataX a, KnownNat n) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Explicit.Prelude: dualFlipFlopSynchronizer :: Clock domain1 gated1 -> Clock domain2 gated2 -> Reset domain2 synchronous -> a -> Signal domain1 a -> Signal domain2 a
+ Clash.Explicit.Prelude: dualFlipFlopSynchronizer :: (NFDataX a, KnownDomain dom1, KnownDomain dom2) => Clock dom1 -> Clock dom2 -> Reset dom2 -> Enable dom2 -> a -> Signal dom1 a -> Signal dom2 a
- Clash.Explicit.Prelude: isFalling :: (Bounded a, Eq a) => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain Bool
+ Clash.Explicit.Prelude: isFalling :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- Clash.Explicit.Prelude: isRising :: (Bounded a, Eq a) => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain Bool
+ Clash.Explicit.Prelude: isRising :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- Clash.Explicit.Prelude: mealy :: Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Signal dom i -> Signal dom o)
+ Clash.Explicit.Prelude: mealy :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Prelude: mealyB :: (Bundle i, Bundle o) => Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Unbundled dom i -> Unbundled dom o)
+ Clash.Explicit.Prelude: mealyB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Prelude: moore :: Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Explicit.Prelude: moore :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Prelude: mooreB :: (Bundle i, Bundle o) => Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Explicit.Prelude: mooreB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Prelude: readNew :: Eq addr => Reset domain synchronous -> Clock domain gated -> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Explicit.Prelude: readNew :: (KnownDomain dom, NFDataX a, Eq addr) => Clock dom -> Reset dom -> Enable dom -> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude: registerB :: Bundle a => Clock domain gated -> Reset domain synchronous -> a -> Unbundled domain a -> Unbundled domain a
+ Clash.Explicit.Prelude: registerB :: (KnownDomain dom, NFDataX a, Bundle a) => Clock dom -> Reset dom -> Enable dom -> a -> Unbundled dom a -> Unbundled dom a
- Clash.Explicit.Prelude: rom :: (KnownNat n, Enum addr) => Clock domain gated -> Vec n a -> Signal domain addr -> Signal domain a
+ Clash.Explicit.Prelude: rom :: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom a
- Clash.Explicit.Prelude: romFile :: (KnownNat m, Enum addr) => Clock domain gated -> SNat n -> FilePath -> Signal domain addr -> Signal domain (BitVector m)
+ Clash.Explicit.Prelude: romFile :: (KnownNat m, Enum addr, KnownDomain dom) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: romFilePow2 :: forall domain gated n m. (KnownNat m, KnownNat n) => Clock domain gated -> FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Explicit.Prelude: romFilePow2 :: forall dom n m. (KnownNat m, KnownNat n, KnownDomain dom) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: romPow2 :: KnownNat n => Clock domain gated -> Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Explicit.Prelude: romPow2 :: (KnownDomain dom, KnownNat n, NFDataX a) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Explicit.Prelude: stimuliGenerator :: forall l domain gated synchronous a. KnownNat l => Clock domain gated -> Reset domain synchronous -> Vec l a -> Signal domain a
+ Clash.Explicit.Prelude: stimuliGenerator :: forall l dom a. (KnownNat l, KnownDomain dom) => Clock dom -> Reset dom -> Vec l a -> Signal dom a
- Clash.Explicit.Prelude: window :: (KnownNat n, Default a) => Clock domain gated -> Reset domain synchronous -> Signal domain a -> Vec (n + 1) (Signal domain a)
+ Clash.Explicit.Prelude: window :: (KnownNat n, KnownDomain dom, NFDataX a, Default a) => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Vec (n + 1) (Signal dom a)
- Clash.Explicit.Prelude: windowD :: (KnownNat n, Default a) => Clock domain gated -> Reset domain synchronous -> Signal domain a -> Vec (n + 1) (Signal domain a)
+ Clash.Explicit.Prelude: windowD :: (KnownNat n, NFDataX a, Default a, KnownDomain dom) => Clock dom -> Reset dom -> Enable dom -> Signal dom a -> Vec (n + 1) (Signal dom a)
- Clash.Explicit.Prelude.Safe: asyncFIFOSynchronizer :: (2 <= addrSize) => SNat addrSize -> Clock wdomain wgated -> Clock rdomain rgated -> Reset wdomain synchronous -> Reset rdomain synchronous -> Signal rdomain Bool -> Signal wdomain (Maybe a) -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)
+ Clash.Explicit.Prelude.Safe: asyncFIFOSynchronizer :: (KnownDomain wdom, KnownDomain rdom, 2 <= addrSize) => SNat addrSize -> Clock wdom -> Clock rdom -> Reset wdom -> Reset rdom -> Enable wdom -> Enable rdom -> Signal rdom Bool -> Signal wdom (Maybe a) -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)
- Clash.Explicit.Prelude.Safe: asyncRam :: (Enum addr, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.Prelude.Safe: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.Prelude.Safe: asyncRamPow2 :: forall wdom rdom wgated rgated n a. (KnownNat n, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
+ Clash.Explicit.Prelude.Safe: asyncRamPow2 :: forall wdom rdom n a. (KnownNat n, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
- Clash.Explicit.Prelude.Safe: blockRam :: HasCallStack => Enum addr => Clock dom gated -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude.Safe: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude.Safe: blockRamPow2 :: (KnownNat n, HasCallStack) => Clock dom gated -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
+ Clash.Explicit.Prelude.Safe: blockRamPow2 :: (KnownDomain dom, HasCallStack, NFDataX a, KnownNat n) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Explicit.Prelude.Safe: dualFlipFlopSynchronizer :: Clock domain1 gated1 -> Clock domain2 gated2 -> Reset domain2 synchronous -> a -> Signal domain1 a -> Signal domain2 a
+ Clash.Explicit.Prelude.Safe: dualFlipFlopSynchronizer :: (NFDataX a, KnownDomain dom1, KnownDomain dom2) => Clock dom1 -> Clock dom2 -> Reset dom2 -> Enable dom2 -> a -> Signal dom1 a -> Signal dom2 a
- Clash.Explicit.Prelude.Safe: isFalling :: (Bounded a, Eq a) => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain Bool
+ Clash.Explicit.Prelude.Safe: isFalling :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- Clash.Explicit.Prelude.Safe: isRising :: (Bounded a, Eq a) => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain Bool
+ Clash.Explicit.Prelude.Safe: isRising :: (KnownDomain dom, NFDataX a, Bounded a, Eq a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom Bool
- Clash.Explicit.Prelude.Safe: mealy :: Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Signal dom i -> Signal dom o)
+ Clash.Explicit.Prelude.Safe: mealy :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Prelude.Safe: mealyB :: (Bundle i, Bundle o) => Clock dom gated -> Reset dom synchronous -> (s -> i -> (s, o)) -> s -> (Unbundled dom i -> Unbundled dom o)
+ Clash.Explicit.Prelude.Safe: mealyB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Prelude.Safe: moore :: Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Explicit.Prelude.Safe: moore :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Explicit.Prelude.Safe: mooreB :: (Bundle i, Bundle o) => Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Explicit.Prelude.Safe: mooreB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Explicit.Prelude.Safe: oscillate :: forall domain gated synchronous n. Clock domain gated -> Reset domain synchronous -> Bool -> SNat n -> Signal domain Bool
+ Clash.Explicit.Prelude.Safe: oscillate :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Bool -> SNat n -> Signal dom Bool
- Clash.Explicit.Prelude.Safe: readNew :: Eq addr => Reset domain synchronous -> Clock domain gated -> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Explicit.Prelude.Safe: readNew :: (KnownDomain dom, NFDataX a, Eq addr) => Clock dom -> Reset dom -> Enable dom -> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude.Safe: registerB :: Bundle a => Clock domain gated -> Reset domain synchronous -> a -> Unbundled domain a -> Unbundled domain a
+ Clash.Explicit.Prelude.Safe: registerB :: (KnownDomain dom, NFDataX a, Bundle a) => Clock dom -> Reset dom -> Enable dom -> a -> Unbundled dom a -> Unbundled dom a
- Clash.Explicit.Prelude.Safe: riseEvery :: forall domain gated synchronous n. Clock domain gated -> Reset domain synchronous -> SNat n -> Signal domain Bool
+ Clash.Explicit.Prelude.Safe: riseEvery :: forall dom n. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> SNat n -> Signal dom Bool
- Clash.Explicit.Prelude.Safe: rom :: (KnownNat n, Enum addr) => Clock domain gated -> Vec n a -> Signal domain addr -> Signal domain a
+ Clash.Explicit.Prelude.Safe: rom :: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom a
- Clash.Explicit.Prelude.Safe: romPow2 :: KnownNat n => Clock domain gated -> Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Explicit.Prelude.Safe: romPow2 :: (KnownDomain dom, KnownNat n, NFDataX a) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Explicit.RAM: asyncRam :: (Enum addr, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.RAM: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.RAM: asyncRam# :: HasCallStack => Clock wdom wgated -> Clock rdom rgated -> SNat n -> Signal rdom Int -> Signal wdom Bool -> Signal wdom Int -> Signal wdom a -> Signal rdom a
+ Clash.Explicit.RAM: asyncRam# :: (HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom Int -> Signal wdom Bool -> Signal wdom Int -> Signal wdom a -> Signal rdom a
- Clash.Explicit.RAM: asyncRamPow2 :: forall wdom rdom wgated rgated n a. (KnownNat n, HasCallStack) => Clock wdom wgated -> Clock rdom rgated -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
+ Clash.Explicit.RAM: asyncRamPow2 :: forall wdom rdom n a. (KnownNat n, HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> Signal rdom (Unsigned n) -> Signal wdom (Maybe (Unsigned n, a)) -> Signal rdom a
- Clash.Explicit.ROM: rom :: (KnownNat n, Enum addr) => Clock domain gated -> Vec n a -> Signal domain addr -> Signal domain a
+ Clash.Explicit.ROM: rom :: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom a
- Clash.Explicit.ROM: rom# :: KnownNat n => Clock domain gated -> Vec n a -> Signal domain Int -> Signal domain a
+ Clash.Explicit.ROM: rom# :: forall dom n a. (KnownDomain dom, KnownNat n, NFDataX a) => Clock dom -> Enable dom -> Vec n a -> Signal dom Int -> Signal dom a
- Clash.Explicit.ROM: romPow2 :: KnownNat n => Clock domain gated -> Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Explicit.ROM: romPow2 :: (KnownDomain dom, KnownNat n, NFDataX a) => Clock dom -> Enable dom -> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Explicit.ROM.File: romFile :: (KnownNat m, Enum addr) => Clock domain gated -> SNat n -> FilePath -> Signal domain addr -> Signal domain (BitVector m)
+ Clash.Explicit.ROM.File: romFile :: (KnownNat m, Enum addr, KnownDomain dom) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (BitVector m)
- Clash.Explicit.ROM.File: romFile# :: KnownNat m => Clock domain gated -> SNat n -> FilePath -> Signal domain Int -> Signal domain (BitVector m)
+ Clash.Explicit.ROM.File: romFile# :: (KnownNat m, KnownDomain dom) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom Int -> Signal dom (BitVector m)
- Clash.Explicit.ROM.File: romFilePow2 :: forall domain gated n m. (KnownNat m, KnownNat n) => Clock domain gated -> FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Explicit.ROM.File: romFilePow2 :: forall dom n m. (KnownNat m, KnownNat n, KnownDomain dom) => Clock dom -> Enable dom -> FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Explicit.Signal: bundle :: (Bundle a, (Signal domain a ~ Unbundled domain a)) => Unbundled domain a -> Signal domain a
+ Clash.Explicit.Signal: bundle :: (Bundle a, Signal dom a ~ Unbundled dom a) => Unbundled dom a -> Signal dom a
- Clash.Explicit.Signal: clockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Clock domain 'Source
+ Clash.Explicit.Signal: clockGen :: KnownDomain dom => Clock dom
- Clash.Explicit.Signal: data Clock (domain :: Domain) (gated :: ClockKind)
+ Clash.Explicit.Signal: data Clock (dom :: Domain)
- Clash.Explicit.Signal: data Reset (domain :: Domain) (synchronous :: ResetKind)
+ Clash.Explicit.Signal: data Reset (dom :: Domain)
- Clash.Explicit.Signal: data Signal (domain :: Domain) a
+ Clash.Explicit.Signal: data Signal (dom :: Domain) a
- Clash.Explicit.Signal: delay :: HasCallStack => Clock domain gated -> Signal domain a -> Signal domain a
+ Clash.Explicit.Signal: delay :: (KnownDomain dom, NFDataX a) => Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
- Clash.Explicit.Signal: fromList :: NFData a => [a] -> Signal domain a
+ Clash.Explicit.Signal: fromList :: NFDataX a => [a] -> Signal dom a
- Clash.Explicit.Signal: fromList_lazy :: [a] -> Signal domain a
+ Clash.Explicit.Signal: fromList_lazy :: [a] -> Signal dom a
- Clash.Explicit.Signal: regEn :: Clock domain clk -> Reset domain synchronous -> a -> Signal domain Bool -> Signal domain a -> Signal domain a
+ Clash.Explicit.Signal: regEn :: (KnownDomain dom, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom Bool -> Signal dom a -> Signal dom a
- Clash.Explicit.Signal: regMaybe :: HasCallStack => Clock domain gated -> Reset domain synchronous -> a -> Signal domain (Maybe a) -> Signal domain a
+ Clash.Explicit.Signal: regMaybe :: (KnownDomain dom, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom (Maybe a) -> Signal dom a
- Clash.Explicit.Signal: register :: HasCallStack => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain a
+ Clash.Explicit.Signal: register :: (KnownDomain dom, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
- Clash.Explicit.Signal: resetSynchronizer :: Clock domain gated -> Reset domain 'Asynchronous -> Reset domain 'Asynchronous
+ Clash.Explicit.Signal: resetSynchronizer :: forall dom. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Reset dom
- Clash.Explicit.Signal: sample :: (Foldable f, NFData a) => f a -> [a]
+ Clash.Explicit.Signal: sample :: (Foldable f, NFDataX a) => f a -> [a]
- Clash.Explicit.Signal: sampleN :: (Foldable f, NFData a) => Int -> f a -> [a]
+ Clash.Explicit.Signal: sampleN :: (Foldable f, NFDataX a) => Int -> f a -> [a]
- Clash.Explicit.Signal: simulate :: (NFData a, NFData b) => (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]
+ Clash.Explicit.Signal: simulate :: (NFDataX a, NFDataX b) => (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
- Clash.Explicit.Signal: simulateB :: (Bundle a, Bundle b, NFData a, NFData b) => (Unbundled domain1 a -> Unbundled domain2 b) -> [a] -> [b]
+ Clash.Explicit.Signal: simulateB :: (Bundle a, Bundle b, NFDataX a, NFDataX b) => (Unbundled dom1 a -> Unbundled dom2 b) -> [a] -> [b]
- Clash.Explicit.Signal: simulateB_lazy :: (Bundle a, Bundle b) => (Unbundled domain1 a -> Unbundled domain2 b) -> [a] -> [b]
+ Clash.Explicit.Signal: simulateB_lazy :: (Bundle a, Bundle b) => (Unbundled dom1 a -> Unbundled dom2 b) -> [a] -> [b]
- Clash.Explicit.Signal: simulate_lazy :: (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]
+ Clash.Explicit.Signal: simulate_lazy :: (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
- Clash.Explicit.Signal: systemClockGen :: Clock System 'Source
+ Clash.Explicit.Signal: systemClockGen :: Clock System
- Clash.Explicit.Signal: systemResetGen :: Reset System 'Asynchronous
+ Clash.Explicit.Signal: systemResetGen :: Reset System
- Clash.Explicit.Signal: type System = 'Dom "system" 10000
+ Clash.Explicit.Signal: type System = ("System" :: Domain)
- Clash.Explicit.Signal: type Unbundled domain a = Signal domain a;
+ Clash.Explicit.Signal: type Unbundled dom a = Signal dom a;
- Clash.Explicit.Signal: type family Unbundled (domain :: Domain) a = res | res -> domain a;
+ Clash.Explicit.Signal: type family Unbundled (dom :: Domain) a = res | res -> dom a;
- Clash.Explicit.Signal: unbundle :: (Bundle a, (Unbundled domain a ~ Signal domain a)) => Signal domain a -> Unbundled domain a
+ Clash.Explicit.Signal: unbundle :: (Bundle a, Unbundled dom a ~ Signal dom a) => Signal dom a -> Unbundled dom a
- Clash.Explicit.Signal: unsafeSynchronizer :: Clock domain1 gated1 -> Clock domain2 gated2 -> Signal domain1 a -> Signal domain2 a
+ Clash.Explicit.Signal: unsafeSynchronizer :: forall dom1 dom2 a. (KnownDomain dom1, KnownDomain dom2) => Clock dom1 -> Clock dom2 -> Signal dom1 a -> Signal dom2 a
- Clash.Explicit.Signal.Delayed: antiDelay :: SNat d -> DSignal domain (n + d) a -> DSignal domain n a
+ Clash.Explicit.Signal.Delayed: antiDelay :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a
- Clash.Explicit.Signal.Delayed: data DSignal (domain :: Domain) (delay :: Nat) a
+ Clash.Explicit.Signal.Delayed: data DSignal (dom :: Domain) (delay :: Nat) a
- Clash.Explicit.Signal.Delayed: delayed :: forall domain gated synchronous a n d. KnownNat d => Clock domain gated -> Reset domain synchronous -> Vec d a -> DSignal domain n a -> DSignal domain (n + d) a
+ Clash.Explicit.Signal.Delayed: delayed :: forall dom a n d. (KnownDomain dom, KnownNat d, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> Vec d a -> DSignal dom n a -> DSignal dom (n + d) a
- Clash.Explicit.Signal.Delayed: delayedI :: (Default a, KnownNat d) => Clock domain gated -> Reset domain synchronous -> DSignal domain n a -> DSignal domain (n + d) a
+ Clash.Explicit.Signal.Delayed: delayedI :: (KnownNat d, KnownDomain dom, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> a -> DSignal dom n a -> DSignal dom (n + d) a
- Clash.Explicit.Signal.Delayed: dfromList :: NFData a => [a] -> DSignal domain 0 a
+ Clash.Explicit.Signal.Delayed: dfromList :: NFDataX a => [a] -> DSignal dom 0 a
- Clash.Explicit.Signal.Delayed: dfromList_lazy :: [a] -> DSignal domain 0 a
+ Clash.Explicit.Signal.Delayed: dfromList_lazy :: [a] -> DSignal dom 0 a
- Clash.Explicit.Signal.Delayed: feedback :: (DSignal domain n a -> (DSignal domain n a, DSignal domain (n + m + 1) a)) -> DSignal domain n a
+ Clash.Explicit.Signal.Delayed: feedback :: (DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)) -> DSignal dom n a
- Clash.Explicit.Signal.Delayed: fromSignal :: Signal domain a -> DSignal domain 0 a
+ Clash.Explicit.Signal.Delayed: fromSignal :: Signal dom a -> DSignal dom 0 a
- Clash.Explicit.Signal.Delayed: toSignal :: DSignal domain delay a -> Signal domain a
+ Clash.Explicit.Signal.Delayed: toSignal :: DSignal dom delay a -> Signal dom a
- Clash.Explicit.Signal.Delayed: unsafeFromSignal :: Signal domain a -> DSignal domain n a
+ Clash.Explicit.Signal.Delayed: unsafeFromSignal :: Signal dom a -> DSignal dom n a
- Clash.Explicit.Synchronizer: asyncFIFOSynchronizer :: (2 <= addrSize) => SNat addrSize -> Clock wdomain wgated -> Clock rdomain rgated -> Reset wdomain synchronous -> Reset rdomain synchronous -> Signal rdomain Bool -> Signal wdomain (Maybe a) -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)
+ Clash.Explicit.Synchronizer: asyncFIFOSynchronizer :: (KnownDomain wdom, KnownDomain rdom, 2 <= addrSize) => SNat addrSize -> Clock wdom -> Clock rdom -> Reset wdom -> Reset rdom -> Enable wdom -> Enable rdom -> Signal rdom Bool -> Signal wdom (Maybe a) -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)
- Clash.Explicit.Synchronizer: dualFlipFlopSynchronizer :: Clock domain1 gated1 -> Clock domain2 gated2 -> Reset domain2 synchronous -> a -> Signal domain1 a -> Signal domain2 a
+ Clash.Explicit.Synchronizer: dualFlipFlopSynchronizer :: (NFDataX a, KnownDomain dom1, KnownDomain dom2) => Clock dom1 -> Clock dom2 -> Reset dom2 -> Enable dom2 -> a -> Signal dom1 a -> Signal dom2 a
- Clash.Explicit.Testbench: assert :: (Eq a, ShowX a) => Clock domain gated -> Reset domain synchronous -> String -> Signal domain a -> Signal domain a -> Signal domain b -> Signal domain b
+ Clash.Explicit.Testbench: assert :: (KnownDomain dom, Eq a, ShowX a) => Clock dom -> Reset dom -> String -> Signal dom a -> Signal dom a -> Signal dom b -> Signal dom b
- Clash.Explicit.Testbench: outputVerifier :: forall l domain gated synchronous a. (KnownNat l, Eq a, ShowX a) => Clock domain gated -> Reset domain synchronous -> Vec l a -> Signal domain a -> Signal domain Bool
+ Clash.Explicit.Testbench: outputVerifier :: forall l a testDom circuitDom. (KnownNat l, KnownDomain testDom, KnownDomain circuitDom, DomainResetKind testDom ~ 'Asynchronous, Eq a, ShowX a) => Clock testDom -> Reset testDom -> Vec l a -> Signal circuitDom a -> Signal testDom Bool
- Clash.Explicit.Testbench: stimuliGenerator :: forall l domain gated synchronous a. KnownNat l => Clock domain gated -> Reset domain synchronous -> Vec l a -> Signal domain a
+ Clash.Explicit.Testbench: stimuliGenerator :: forall l dom a. (KnownNat l, KnownDomain dom) => Clock dom -> Reset dom -> Vec l a -> Signal dom a
- Clash.Hidden: expose :: forall x a r. (Hidden x a => r) -> (a -> r)
+ Clash.Hidden: expose :: forall x a r. (Hidden x a => r) -> a -> r
- Clash.Intel.ClockGen: alteraPll :: forall pllOut pllIn name. SSymbol name -> Clock pllIn 'Source -> Reset pllIn 'Asynchronous -> (Clock pllOut 'Source, Signal pllOut Bool)
+ Clash.Intel.ClockGen: alteraPll :: Clocks t => SSymbol name -> Clock domIn -> Reset domIn -> t
- Clash.Intel.ClockGen: altpll :: forall pllOut pllIn name. SSymbol name -> Clock pllIn 'Source -> Reset pllIn 'Asynchronous -> (Clock pllOut 'Source, Signal pllOut Bool)
+ Clash.Intel.ClockGen: altpll :: forall domOut domIn name. SSymbol name -> Clock domIn -> Reset domIn -> (Clock domOut, Signal domOut Bool)
- Clash.Intel.DDR: altddioIn :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast), KnownNat m) => SSymbol deviceFamily -> Clock slow gated -> Reset slow synchronous -> Signal fast (BitVector m) -> Signal slow (BitVector m, BitVector m)
+ Clash.Intel.DDR: altddioIn :: (HasCallStack, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity), KnownNat m) => SSymbol deviceFamily -> Clock slow -> Reset slow -> Enable slow -> Signal fast (BitVector m) -> Signal slow (BitVector m, BitVector m)
- Clash.Intel.DDR: altddioOut :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast), KnownNat m) => SSymbol deviceFamily -> Clock slow gated -> Reset slow synchronous -> Signal slow (BitVector m, BitVector m) -> Signal fast (BitVector m)
+ Clash.Intel.DDR: altddioOut :: (HasCallStack, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity), KnownNat m) => SSymbol deviceFamily -> Clock slow -> Reset slow -> Enable slow -> Signal slow (BitVector m, BitVector m) -> Signal fast (BitVector m)
- Clash.Prelude: (<^>) :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude: (<^>) :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude: asyncRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => SNat n -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: asyncRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude: asyncRamPow2 :: (KnownNat n, HiddenClock dom, HiddenEnable dom, HasCallStack) => Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude: blockRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => Vec n a -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: blockRamFile :: (KnownNat m, Enum addr, HiddenClock domain gated, HasCallStack) => SNat n -> FilePath -> Signal domain addr -> Signal domain (Maybe (addr, BitVector m)) -> Signal domain (BitVector m)
+ Clash.Prelude: blockRamFile :: (KnownNat m, Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude: blockRamFilePow2 :: forall domain gated n m. (KnownNat m, KnownNat n, HiddenClock domain gated, HasCallStack) => FilePath -> Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, BitVector m)) -> Signal domain (BitVector m)
+ Clash.Prelude: blockRamFilePow2 :: forall dom n m. (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom, HasCallStack) => FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude: blockRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude: blockRamPow2 :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, KnownNat n) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude: infixr 3 &&
+ Clash.Prelude: infixr 3 `registerB`
- Clash.Prelude: isFalling :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) => a -> Signal domain a -> Signal domain Bool
+ Clash.Prelude: isFalling :: (HiddenClockResetEnable dom, NFDataX a, Bounded a, Eq a) => a -> Signal dom a -> Signal dom Bool
- Clash.Prelude: isRising :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) => a -> Signal domain a -> Signal domain Bool
+ Clash.Prelude: isRising :: (HiddenClockResetEnable dom, NFDataX a, Bounded a, Eq a) => a -> Signal dom a -> Signal dom Bool
- Clash.Prelude: mealy :: HiddenClockReset domain gated synchronous => (s -> i -> (s, o)) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude: mealy :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude: mealyB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude: mealyB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude: moore :: HiddenClockReset domain gated synchronous => (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude: moore :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude: mooreB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude: mooreB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude: oscillate :: HiddenClockReset domain gated synchronous => Bool -> SNat n -> Signal domain Bool
+ Clash.Prelude: oscillate :: HiddenClockResetEnable dom => Bool -> SNat n -> Signal dom Bool
- Clash.Prelude: readNew :: (Eq addr, HiddenClockReset domain gated synchronous) => (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude: readNew :: (HiddenClockResetEnable dom, NFDataX a, Eq addr) => (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: registerB :: (HiddenClockReset domain gated synchronous, Bundle a) => a -> Unbundled domain a -> Unbundled domain a
+ Clash.Prelude: registerB :: (HiddenClockResetEnable dom, NFDataX a, Bundle a) => a -> Unbundled dom a -> Unbundled dom a
- Clash.Prelude: riseEvery :: HiddenClockReset domain gated synchronous => SNat n -> Signal domain Bool
+ Clash.Prelude: riseEvery :: HiddenClockResetEnable dom => SNat n -> Signal dom Bool
- Clash.Prelude: rom :: (KnownNat n, KnownNat m, HiddenClock domain gated) => Vec n a -> Signal domain (Unsigned m) -> Signal domain a
+ Clash.Prelude: rom :: forall dom n m a. (NFDataX a, KnownNat n, KnownNat m, HiddenClock dom, HiddenEnable dom) => Vec n a -> Signal dom (Unsigned m) -> Signal dom a
- Clash.Prelude: romFile :: (KnownNat m, KnownNat n, HiddenClock domain gated) => SNat n -> FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Prelude: romFile :: (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom) => SNat n -> FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Prelude: romFilePow2 :: forall n m domain gated. (KnownNat m, KnownNat n, HiddenClock domain gated) => FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Prelude: romFilePow2 :: forall n m dom. (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom) => FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Prelude: romPow2 :: (KnownNat n, HiddenClock domain gated) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Prelude: romPow2 :: forall dom n a. (KnownNat n, NFDataX a, HiddenClock dom, HiddenEnable dom) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Prelude: window :: (KnownNat n, Default a, HiddenClockReset domain gated synchronous) => Signal domain a -> Vec (n + 1) (Signal domain a)
+ Clash.Prelude: window :: (HiddenClockResetEnable dom, KnownNat n, Default a, NFDataX a) => Signal dom a -> Vec (n + 1) (Signal dom a)
- Clash.Prelude: windowD :: (KnownNat n, Default a, HiddenClockReset domain gated synchronous) => Signal domain a -> Vec (n + 1) (Signal domain a)
+ Clash.Prelude: windowD :: (HiddenClockResetEnable dom, KnownNat n, Default a, NFDataX a) => Signal dom a -> Vec (n + 1) (Signal dom a)
- Clash.Prelude.BitIndex: setSlice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> BitVector (m + 1 - n) -> a -> a
+ Clash.Prelude.BitIndex: setSlice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> BitVector ((m + 1) - n) -> a -> a
- Clash.Prelude.BitIndex: slice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> a -> BitVector (m + 1 - n)
+ Clash.Prelude.BitIndex: slice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> a -> BitVector ((m + 1) - n)
- Clash.Prelude.BitReduction: reduceOr :: BitPack a => a -> Bit
+ Clash.Prelude.BitReduction: reduceOr :: (BitPack a, KnownNat (BitSize a)) => a -> Bit
- Clash.Prelude.BitReduction: reduceXor :: BitPack a => a -> Bit
+ Clash.Prelude.BitReduction: reduceXor :: (BitPack a, KnownNat (BitSize a)) => a -> Bit
- Clash.Prelude.BlockRam: blockRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => Vec n a -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.BlockRam: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.BlockRam: blockRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude.BlockRam: blockRamPow2 :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, KnownNat n) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude.BlockRam: readNew :: (Eq addr, HiddenClockReset domain gated synchronous) => (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.BlockRam: readNew :: (HiddenClockResetEnable dom, NFDataX a, Eq addr) => (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.BlockRam.File: blockRamFile :: (KnownNat m, Enum addr, HiddenClock domain gated, HasCallStack) => SNat n -> FilePath -> Signal domain addr -> Signal domain (Maybe (addr, BitVector m)) -> Signal domain (BitVector m)
+ Clash.Prelude.BlockRam.File: blockRamFile :: (KnownNat m, Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude.BlockRam.File: blockRamFilePow2 :: forall domain gated n m. (KnownNat m, KnownNat n, HiddenClock domain gated, HasCallStack) => FilePath -> Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, BitVector m)) -> Signal domain (BitVector m)
+ Clash.Prelude.BlockRam.File: blockRamFilePow2 :: forall dom n m. (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom, HasCallStack) => FilePath -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude.DataFlow: DF :: Signal domain i -> Signal domain iEn -> Signal domain oEn -> (Signal domain o, Signal domain oEn, Signal domain iEn) -> DataFlow domain iEn oEn i o
+ Clash.Prelude.DataFlow: DF :: (Signal dom i -> Signal dom iEn -> Signal dom oEn -> (Signal dom o, Signal dom oEn, Signal dom iEn)) -> DataFlow dom iEn oEn i o
- Clash.Prelude.DataFlow: [df] :: DataFlow domain iEn oEn i o -> Signal domain i -> Signal domain iEn -> Signal domain oEn -> (Signal domain o, Signal domain oEn, Signal domain iEn)
+ Clash.Prelude.DataFlow: [df] :: DataFlow dom iEn oEn i o -> Signal dom i -> Signal dom iEn -> Signal dom oEn -> (Signal dom o, Signal dom oEn, Signal dom iEn)
- Clash.Prelude.DataFlow: fifoDF :: forall addrSize m n a domain gated synchronous. (KnownNat addrSize, KnownNat n, KnownNat m, (m + n) ~ (2 ^ addrSize)) => Clock domain gated -> Reset domain synchronous -> SNat (m + n) -> Vec m a -> DataFlow domain Bool Bool a a
+ Clash.Prelude.DataFlow: fifoDF :: forall addrSize m n a dom. (KnownDomain dom, NFDataX a, KnownNat addrSize, KnownNat n, KnownNat m, (m + n) ~ (2 ^ addrSize)) => Clock dom -> Reset dom -> Enable dom -> SNat (m + n) -> Vec m a -> DataFlow dom Bool Bool a a
- Clash.Prelude.DataFlow: loopDF :: (KnownNat m, KnownNat n, KnownNat addrSize, (m + n) ~ (2 ^ addrSize)) => Clock dom gated -> Reset dom synchronous -> SNat (m + n) -> Vec m d -> DataFlow dom (Bool, Bool) (Bool, Bool) (a, d) (b, d) -> DataFlow dom Bool Bool a b
+ Clash.Prelude.DataFlow: loopDF :: (KnownDomain dom, NFDataX d, KnownNat m, KnownNat n, KnownNat addrSize, (m + n) ~ (2 ^ addrSize)) => Clock dom -> Reset dom -> Enable dom -> SNat (m + n) -> Vec m d -> DataFlow dom (Bool, Bool) (Bool, Bool) (a, d) (b, d) -> DataFlow dom Bool Bool a b
- Clash.Prelude.DataFlow: mealyDF :: Clock domain gated -> Reset domain synchronous -> (s -> i -> (s, o)) -> s -> DataFlow domain Bool Bool i o
+ Clash.Prelude.DataFlow: mealyDF :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> (s, o)) -> s -> DataFlow dom Bool Bool i o
- Clash.Prelude.DataFlow: mooreDF :: Clock domain gated -> Reset domain synchronous -> (s -> i -> s) -> (s -> o) -> s -> DataFlow domain Bool Bool i o
+ Clash.Prelude.DataFlow: mooreDF :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (s -> i -> s) -> (s -> o) -> s -> DataFlow dom Bool Bool i o
- Clash.Prelude.DataFlow: newtype DataFlow domain iEn oEn i o
+ Clash.Prelude.DataFlow: newtype DataFlow dom iEn oEn i o
- Clash.Prelude.Mealy: (<^>) :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Mealy: (<^>) :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.Mealy: mealy :: HiddenClockReset domain gated synchronous => (s -> i -> (s, o)) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude.Mealy: mealy :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude.Mealy: mealyB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Mealy: mealyB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.Moore: medvedev :: HiddenClockReset domain gated synchronous => (s -> i -> s) -> s -> (Signal domain i -> Signal domain s)
+ Clash.Prelude.Moore: medvedev :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> s) -> s -> Signal dom i -> Signal dom s
- Clash.Prelude.Moore: medvedevB :: (Bundle i, Bundle s, HiddenClockReset domain gated synchronous) => (s -> i -> s) -> s -> (Unbundled domain i -> Unbundled domain s)
+ Clash.Prelude.Moore: medvedevB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle s) => (s -> i -> s) -> s -> Unbundled dom i -> Unbundled dom s
- Clash.Prelude.Moore: moore :: HiddenClockReset domain gated synchronous => (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude.Moore: moore :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude.Moore: mooreB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Moore: mooreB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.RAM: asyncRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => SNat n -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.RAM: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.RAM: asyncRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude.RAM: asyncRamPow2 :: (KnownNat n, HiddenClock dom, HiddenEnable dom, HasCallStack) => Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude.ROM: rom :: (KnownNat n, KnownNat m, HiddenClock domain gated) => Vec n a -> Signal domain (Unsigned m) -> Signal domain a
+ Clash.Prelude.ROM: rom :: forall dom n m a. (NFDataX a, KnownNat n, KnownNat m, HiddenClock dom, HiddenEnable dom) => Vec n a -> Signal dom (Unsigned m) -> Signal dom a
- Clash.Prelude.ROM: romPow2 :: (KnownNat n, HiddenClock domain gated) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Prelude.ROM: romPow2 :: forall dom n a. (KnownNat n, NFDataX a, HiddenClock dom, HiddenEnable dom) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Prelude.ROM.File: romFile :: (KnownNat m, KnownNat n, HiddenClock domain gated) => SNat n -> FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Prelude.ROM.File: romFile :: (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom) => SNat n -> FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Prelude.ROM.File: romFilePow2 :: forall n m domain gated. (KnownNat m, KnownNat n, HiddenClock domain gated) => FilePath -> Signal domain (Unsigned n) -> Signal domain (BitVector m)
+ Clash.Prelude.ROM.File: romFilePow2 :: forall n m dom. (KnownNat m, KnownNat n, HiddenClock dom, HiddenEnable dom) => FilePath -> Signal dom (Unsigned n) -> Signal dom (BitVector m)
- Clash.Prelude.Safe: (<^>) :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Safe: (<^>) :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.Safe: asyncRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => SNat n -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.Safe: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.Safe: asyncRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude.Safe: asyncRamPow2 :: (KnownNat n, HiddenClock dom, HiddenEnable dom, HasCallStack) => Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude.Safe: blockRam :: (Enum addr, HiddenClock domain gated, HasCallStack) => Vec n a -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.Safe: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.Safe: blockRamPow2 :: (KnownNat n, HiddenClock domain gated, HasCallStack) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain (Maybe (Unsigned n, a)) -> Signal domain a
+ Clash.Prelude.Safe: blockRamPow2 :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, KnownNat n) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, a)) -> Signal dom a
- Clash.Prelude.Safe: infixr 3 &&
+ Clash.Prelude.Safe: infixr 3 `registerB`
- Clash.Prelude.Safe: isFalling :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) => a -> Signal domain a -> Signal domain Bool
+ Clash.Prelude.Safe: isFalling :: (HiddenClockResetEnable dom, NFDataX a, Bounded a, Eq a) => a -> Signal dom a -> Signal dom Bool
- Clash.Prelude.Safe: isRising :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) => a -> Signal domain a -> Signal domain Bool
+ Clash.Prelude.Safe: isRising :: (HiddenClockResetEnable dom, NFDataX a, Bounded a, Eq a) => a -> Signal dom a -> Signal dom Bool
- Clash.Prelude.Safe: mealy :: HiddenClockReset domain gated synchronous => (s -> i -> (s, o)) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude.Safe: mealy :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> (s, o)) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude.Safe: mealyB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> (s, o)) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Safe: mealyB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> (s, o)) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.Safe: moore :: HiddenClockReset domain gated synchronous => (s -> i -> s) -> (s -> o) -> s -> (Signal domain i -> Signal domain o)
+ Clash.Prelude.Safe: moore :: (HiddenClockResetEnable dom, NFDataX s) => (s -> i -> s) -> (s -> o) -> s -> Signal dom i -> Signal dom o
- Clash.Prelude.Safe: mooreB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) => (s -> i -> s) -> (s -> o) -> s -> (Unbundled domain i -> Unbundled domain o)
+ Clash.Prelude.Safe: mooreB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (s -> i -> s) -> (s -> o) -> s -> Unbundled dom i -> Unbundled dom o
- Clash.Prelude.Safe: oscillate :: HiddenClockReset domain gated synchronous => Bool -> SNat n -> Signal domain Bool
+ Clash.Prelude.Safe: oscillate :: HiddenClockResetEnable dom => Bool -> SNat n -> Signal dom Bool
- Clash.Prelude.Safe: readNew :: (Eq addr, HiddenClockReset domain gated synchronous) => (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a) -> Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a
+ Clash.Prelude.Safe: readNew :: (HiddenClockResetEnable dom, NFDataX a, Eq addr) => (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.Safe: registerB :: (HiddenClockReset domain gated synchronous, Bundle a) => a -> Unbundled domain a -> Unbundled domain a
+ Clash.Prelude.Safe: registerB :: (HiddenClockResetEnable dom, NFDataX a, Bundle a) => a -> Unbundled dom a -> Unbundled dom a
- Clash.Prelude.Safe: riseEvery :: HiddenClockReset domain gated synchronous => SNat n -> Signal domain Bool
+ Clash.Prelude.Safe: riseEvery :: HiddenClockResetEnable dom => SNat n -> Signal dom Bool
- Clash.Prelude.Safe: rom :: (KnownNat n, KnownNat m, HiddenClock domain gated) => Vec n a -> Signal domain (Unsigned m) -> Signal domain a
+ Clash.Prelude.Safe: rom :: forall dom n m a. (NFDataX a, KnownNat n, KnownNat m, HiddenClock dom, HiddenEnable dom) => Vec n a -> Signal dom (Unsigned m) -> Signal dom a
- Clash.Prelude.Safe: romPow2 :: (KnownNat n, HiddenClock domain gated) => Vec (2 ^ n) a -> Signal domain (Unsigned n) -> Signal domain a
+ Clash.Prelude.Safe: romPow2 :: forall dom n a. (KnownNat n, NFDataX a, HiddenClock dom, HiddenEnable dom) => Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
- Clash.Prelude.Testbench: assert :: (Eq a, ShowX a, HiddenClockReset domain gated synchronous) => String -> Signal domain a -> Signal domain a -> Signal domain b -> Signal domain b
+ Clash.Prelude.Testbench: assert :: (Eq a, ShowX a, HiddenClock dom, HiddenReset dom) => String -> Signal dom a -> Signal dom a -> Signal dom b -> Signal dom b
- Clash.Prelude.Testbench: stimuliGenerator :: (KnownNat l, HiddenClockReset domain gated synchronous) => Vec l a -> Signal domain a
+ Clash.Prelude.Testbench: stimuliGenerator :: (KnownNat l, HiddenClock dom, HiddenReset dom) => Vec l a -> Signal dom a
- Clash.Promoted.Nat: data BNat :: Nat -> *
+ Clash.Promoted.Nat: data BNat :: Nat -> Type
- Clash.Promoted.Nat: data UNat :: Nat -> *
+ Clash.Promoted.Nat: data UNat :: Nat -> Type
- Clash.Promoted.Nat: div2Sub1BNat :: BNat (2 * n + 1) -> BNat n
+ Clash.Promoted.Nat: div2Sub1BNat :: BNat ((2 * n) + 1) -> BNat n
- Clash.Promoted.Nat: divSNat :: (1 <= b) => SNat a -> SNat b -> SNat (Div a b)
+ Clash.Promoted.Nat: divSNat :: 1 <= b => SNat a -> SNat b -> SNat (Div a b)
- Clash.Promoted.Nat: leToPlus :: forall (k :: Nat) (n :: Nat) f r. (k <= n) => f n -> (forall m. f (m + k) -> r) -> r
+ Clash.Promoted.Nat: leToPlus :: forall (k :: Nat) (n :: Nat) r. k <= n => (forall m. n ~ (k + m) => r) -> r
- Clash.Promoted.Nat: leToPlusKN :: forall (k :: Nat) (n :: Nat) f r. (k <= n, KnownNat n, KnownNat k) => f n -> (forall m. KnownNat m => f (m + k) -> r) -> r
+ Clash.Promoted.Nat: leToPlusKN :: forall (k :: Nat) (n :: Nat) r. (k <= n, KnownNat k, KnownNat n) => (forall m. (n ~ (k + m), KnownNat m) => r) -> r
- Clash.Promoted.Nat: logBaseSNat :: (FLog base x ~ CLog base x) => SNat base -> SNat x -> SNat (Log base x)
+ Clash.Promoted.Nat: logBaseSNat :: FLog base x ~ CLog base x => SNat base -> SNat x -> SNat (Log base x)
- Clash.Promoted.Nat: modSNat :: (1 <= b) => SNat a -> SNat b -> SNat (Mod a b)
+ Clash.Promoted.Nat: modSNat :: 1 <= b => SNat a -> SNat b -> SNat (Mod a b)
- Clash.Promoted.Nat: predBNat :: (1 <= n) => BNat n -> BNat (n - 1)
+ Clash.Promoted.Nat: predBNat :: 1 <= n => BNat n -> BNat (n - 1)
- Clash.Promoted.Nat: snatToNum :: Num a => SNat n -> a
+ Clash.Promoted.Nat: snatToNum :: forall a n. Num a => SNat n -> a
- Clash.Promoted.Nat: toUNat :: SNat n -> UNat n
+ Clash.Promoted.Nat: toUNat :: forall n. SNat n -> UNat n
- Clash.Signal: bundle :: (Bundle a, (Signal domain a ~ Unbundled domain a)) => Unbundled domain a -> Signal domain a
+ Clash.Signal: bundle :: (Bundle a, Signal dom a ~ Unbundled dom a) => Unbundled dom a -> Signal dom a
- Clash.Signal: clockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Clock domain 'Source
+ Clash.Signal: clockGen :: KnownDomain dom => Clock dom
- Clash.Signal: data Clock (domain :: Domain) (gated :: ClockKind)
+ Clash.Signal: data Clock (dom :: Domain)
- Clash.Signal: data Reset (domain :: Domain) (synchronous :: ResetKind)
+ Clash.Signal: data Reset (dom :: Domain)
- Clash.Signal: data Signal (domain :: Domain) a
+ Clash.Signal: data Signal (dom :: Domain) a
- Clash.Signal: delay :: (HiddenClock domain gated, HasCallStack) => Signal domain a -> Signal domain a
+ Clash.Signal: delay :: forall dom a. (NFDataX a, HiddenClock dom, HiddenEnable dom) => a -> Signal dom a -> Signal dom a
- Clash.Signal: exposeClock :: (HiddenClock domain gated => r) -> (Clock domain gated -> r)
+ Clash.Signal: exposeClock :: forall dom r. (HiddenClock dom => r) -> KnownDomain dom => Clock dom -> r
- Clash.Signal: exposeReset :: (HiddenReset domain synchronous => r) -> (Reset domain synchronous -> r)
+ Clash.Signal: exposeReset :: forall dom r. (HiddenReset dom => r) -> KnownDomain dom => Reset dom -> r
- Clash.Signal: fromList :: NFData a => [a] -> Signal domain a
+ Clash.Signal: fromList :: NFDataX a => [a] -> Signal dom a
- Clash.Signal: fromList_lazy :: [a] -> Signal domain a
+ Clash.Signal: fromList_lazy :: [a] -> Signal dom a
- Clash.Signal: hasClock :: HiddenClock domain gated => Clock domain gated
+ Clash.Signal: hasClock :: forall dom. HiddenClock dom => Clock dom
- Clash.Signal: hasReset :: HiddenReset domain synchronous => Reset domain synchronous
+ Clash.Signal: hasReset :: forall dom. HiddenReset dom => Reset dom
- Clash.Signal: hideClock :: HiddenClock domain gated => (Clock domain gated -> r) -> r
+ Clash.Signal: hideClock :: forall dom r. HiddenClock dom => (Clock dom -> r) -> r
- Clash.Signal: hideReset :: HiddenReset domain synchronous => (Reset domain synchronous -> r) -> r
+ Clash.Signal: hideReset :: forall dom r. HiddenReset dom => (Reset dom -> r) -> r
- Clash.Signal: regEn :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain Bool -> Signal domain a -> Signal domain a
+ Clash.Signal: regEn :: forall dom a. (HiddenClockResetEnable dom, NFDataX a) => a -> Signal dom Bool -> Signal dom a -> Signal dom a
- Clash.Signal: regMaybe :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain (Maybe a) -> Signal domain a
+ Clash.Signal: regMaybe :: forall dom a. (HiddenClockResetEnable dom, NFDataX a) => a -> Signal dom (Maybe a) -> Signal dom a
- Clash.Signal: register :: (HiddenClockReset domain gated synchronous, HasCallStack) => a -> Signal domain a -> Signal domain a
+ Clash.Signal: register :: forall dom a. (HiddenClockResetEnable dom, NFDataX a) => a -> Signal dom a -> Signal dom a
- Clash.Signal: resetSynchronizer :: Clock domain gated -> Reset domain 'Asynchronous -> Reset domain 'Asynchronous
+ Clash.Signal: resetSynchronizer :: forall dom. KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> Reset dom
- Clash.Signal: sample :: forall gated synchronous domain a. NFData a => (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
+ Clash.Signal: sample :: forall dom a. (KnownDomain dom, NFDataX a) => (HiddenClockResetEnable dom => Signal dom a) -> [a]
- Clash.Signal: sampleN :: forall gated synchronous domain a. NFData a => Int -> (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
+ Clash.Signal: sampleN :: forall dom a. (KnownDomain dom, NFDataX a) => Int -> (HiddenClockResetEnable dom => Signal dom a) -> [a]
- Clash.Signal: sampleN_lazy :: forall gated synchronous domain a. Int -> (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
+ Clash.Signal: sampleN_lazy :: forall dom a. KnownDomain dom => Int -> (HiddenClockResetEnable dom => Signal dom a) -> [a]
- Clash.Signal: sample_lazy :: forall gated synchronous domain a. (HiddenClockReset domain gated synchronous => Signal domain a) -> [a]
+ Clash.Signal: sample_lazy :: forall dom a. KnownDomain dom => (HiddenClockResetEnable dom => Signal dom a) -> [a]
- Clash.Signal: simulate :: forall gated synchronous domain a b. (NFData a, NFData b) => (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b) -> [a] -> [b]
+ Clash.Signal: simulate :: forall dom a b. (KnownDomain dom, NFDataX a, NFDataX b) => (HiddenClockResetEnable dom => Signal dom a -> Signal dom b) -> [a] -> [b]
- Clash.Signal: simulateB :: forall gated synchronous domain a b. (Bundle a, Bundle b, NFData a, NFData b) => (HiddenClockReset domain gated synchronous => Unbundled domain a -> Unbundled domain b) -> [a] -> [b]
+ Clash.Signal: simulateB :: forall dom a b. (KnownDomain dom, Bundle a, Bundle b, NFDataX a, NFDataX b) => (HiddenClockResetEnable dom => Unbundled dom a -> Unbundled dom b) -> [a] -> [b]
- Clash.Signal: simulateB_lazy :: forall gated synchronous domain a b. (Bundle a, Bundle b) => (HiddenClockReset domain gated synchronous => Unbundled domain a -> Unbundled domain b) -> [a] -> [b]
+ Clash.Signal: simulateB_lazy :: forall dom a b. (KnownDomain dom, Bundle a, Bundle b) => (HiddenClockResetEnable dom => Unbundled dom a -> Unbundled dom b) -> [a] -> [b]
- Clash.Signal: simulate_lazy :: forall gated synchronous domain a b. (HiddenClockReset domain gated synchronous => Signal domain a -> Signal domain b) -> [a] -> [b]
+ Clash.Signal: simulate_lazy :: forall dom a b. KnownDomain dom => (HiddenClockResetEnable dom => Signal dom a -> Signal dom b) -> [a] -> [b]
- Clash.Signal: systemClockGen :: Clock System 'Source
+ Clash.Signal: systemClockGen :: Clock System
- Clash.Signal: systemResetGen :: Reset System 'Asynchronous
+ Clash.Signal: systemResetGen :: Reset System
- Clash.Signal: testFor :: Int -> (HiddenClockReset domain gated synchronous => Signal domain Bool) -> Property
+ Clash.Signal: testFor :: KnownDomain dom => Int -> (HiddenClockResetEnable dom => Signal dom Bool) -> Property
- Clash.Signal: type HiddenClock domain gated = Hidden "clk" (Clock domain gated)
+ Clash.Signal: type HiddenClock dom = (Hidden (HiddenClockName dom) (Clock dom), KnownDomain dom)
- Clash.Signal: type HiddenReset domain synchronous = Hidden "rst" (Reset domain synchronous)
+ Clash.Signal: type HiddenReset dom = (Hidden (HiddenResetName dom) (Reset dom), KnownDomain dom)
- Clash.Signal: type System = 'Dom "system" 10000
+ Clash.Signal: type System = ("System" :: Domain)
- Clash.Signal: type Unbundled domain a = Signal domain a;
+ Clash.Signal: type Unbundled dom a = Signal dom a;
- Clash.Signal: type family Unbundled (domain :: Domain) a = res | res -> domain a;
+ Clash.Signal: type family Unbundled (dom :: Domain) a = res | res -> dom a;
- Clash.Signal: unbundle :: (Bundle a, (Unbundled domain a ~ Signal domain a)) => Signal domain a -> Unbundled domain a
+ Clash.Signal: unbundle :: (Bundle a, Unbundled dom a ~ Signal dom a) => Signal dom a -> Unbundled dom a
- Clash.Signal: withClock :: Clock domain gated -> (HiddenClock domain gated => r) -> r
+ Clash.Signal: withClock :: forall dom r. KnownDomain dom => Clock dom -> (HiddenClock dom => r) -> r
- Clash.Signal: withReset :: Reset domain synchronous -> (HiddenReset domain synchronous => r) -> r
+ Clash.Signal: withReset :: forall dom r. KnownDomain dom => Reset dom -> (HiddenReset dom => r) -> r
- Clash.Signal.Bundle: bundle :: (Bundle a, (Signal domain a ~ Unbundled domain a)) => Unbundled domain a -> Signal domain a
+ Clash.Signal.Bundle: bundle :: (Bundle a, Signal dom a ~ Unbundled dom a) => Unbundled dom a -> Signal dom a
- Clash.Signal.Bundle: type Unbundled domain a = Signal domain a;
+ Clash.Signal.Bundle: type Unbundled dom a = Signal dom a;
- Clash.Signal.Bundle: type family Unbundled (domain :: Domain) a = res | res -> domain a;
+ Clash.Signal.Bundle: type family Unbundled (dom :: Domain) a = res | res -> dom a;
- Clash.Signal.Bundle: unbundle :: (Bundle a, (Unbundled domain a ~ Signal domain a)) => Signal domain a -> Unbundled domain a
+ Clash.Signal.Bundle: unbundle :: (Bundle a, Unbundled dom a ~ Signal dom a) => Signal dom a -> Unbundled dom a
- Clash.Signal.Delayed: antiDelay :: SNat d -> DSignal domain (n + d) a -> DSignal domain n a
+ Clash.Signal.Delayed: antiDelay :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a
- Clash.Signal.Delayed: data DSignal (domain :: Domain) (delay :: Nat) a
+ Clash.Signal.Delayed: data DSignal (dom :: Domain) (delay :: Nat) a
- Clash.Signal.Delayed: delayed :: (KnownNat d, HiddenClockReset domain gated synchronous) => Vec d a -> DSignal domain n a -> DSignal domain (n + d) a
+ Clash.Signal.Delayed: delayed :: (KnownNat d, HiddenClockResetEnable dom, NFDataX a) => Vec d a -> DSignal dom n a -> DSignal dom (n + d) a
- Clash.Signal.Delayed: delayedI :: (Default a, KnownNat d, HiddenClockReset domain gated synchronous) => DSignal domain n a -> DSignal domain (n + d) a
+ Clash.Signal.Delayed: delayedI :: (KnownNat d, NFDataX a, HiddenClockResetEnable dom) => a -> DSignal dom n a -> DSignal dom (n + d) a
- Clash.Signal.Delayed: dfromList :: NFData a => [a] -> DSignal domain 0 a
+ Clash.Signal.Delayed: dfromList :: NFDataX a => [a] -> DSignal dom 0 a
- Clash.Signal.Delayed: dfromList_lazy :: [a] -> DSignal domain 0 a
+ Clash.Signal.Delayed: dfromList_lazy :: [a] -> DSignal dom 0 a
- Clash.Signal.Delayed: feedback :: (DSignal domain n a -> (DSignal domain n a, DSignal domain (n + m + 1) a)) -> DSignal domain n a
+ Clash.Signal.Delayed: feedback :: (DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)) -> DSignal dom n a
- Clash.Signal.Delayed: fromSignal :: Signal domain a -> DSignal domain 0 a
+ Clash.Signal.Delayed: fromSignal :: Signal dom a -> DSignal dom 0 a
- Clash.Signal.Delayed: toSignal :: DSignal domain delay a -> Signal domain a
+ Clash.Signal.Delayed: toSignal :: DSignal dom delay a -> Signal dom a
- Clash.Signal.Delayed: unsafeFromSignal :: Signal domain a -> DSignal domain n a
+ Clash.Signal.Delayed: unsafeFromSignal :: Signal dom a -> DSignal dom n a
- Clash.Signal.Internal: (:-) :: a -> Signal domain a -> Signal a
+ Clash.Signal.Internal: (:-) :: a -> Signal dom a -> Signal (dom :: Domain) a
- Clash.Signal.Internal: appSignal# :: Signal domain (a -> b) -> Signal domain a -> Signal domain b
+ Clash.Signal.Internal: appSignal# :: Signal dom (a -> b) -> Signal dom a -> Signal dom b
- Clash.Signal.Internal: clockGen :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period) => Clock domain 'Source
+ Clash.Signal.Internal: clockGen :: KnownDomain dom => Clock dom
- Clash.Signal.Internal: data Clock (domain :: Domain) (gated :: ClockKind)
+ Clash.Signal.Internal: data Clock (dom :: Domain)
- Clash.Signal.Internal: data Reset (domain :: Domain) (synchronous :: ResetKind)
+ Clash.Signal.Internal: data Reset (dom :: Domain)
- Clash.Signal.Internal: data Signal (domain :: Domain) a
+ Clash.Signal.Internal: data Signal (dom :: Domain) a
- Clash.Signal.Internal: delay# :: HasCallStack => Clock domain gated -> Signal domain a -> Signal domain a
+ Clash.Signal.Internal: delay# :: forall dom a. (KnownDomain dom, NFDataX a) => Clock dom -> Enable dom -> a -> Signal dom a -> Signal dom a
- Clash.Signal.Internal: foldr# :: (a -> b -> b) -> b -> Signal domain a -> b
+ Clash.Signal.Internal: foldr# :: (a -> b -> b) -> b -> Signal dom a -> b
- Clash.Signal.Internal: fromList :: NFData a => [a] -> Signal domain a
+ Clash.Signal.Internal: fromList :: NFDataX a => [a] -> Signal dom a
- Clash.Signal.Internal: fromList_lazy :: [a] -> Signal domain a
+ Clash.Signal.Internal: fromList_lazy :: [a] -> Signal dom a
- Clash.Signal.Internal: joinSignal# :: Signal domain (Signal domain a) -> Signal domain a
+ Clash.Signal.Internal: joinSignal# :: Signal dom (Signal dom a) -> Signal dom a
- Clash.Signal.Internal: mapSignal# :: (a -> b) -> Signal domain a -> Signal domain b
+ Clash.Signal.Internal: mapSignal# :: (a -> b) -> Signal dom a -> Signal dom b
- Clash.Signal.Internal: register# :: HasCallStack => Clock domain gated -> Reset domain synchronous -> a -> Signal domain a -> Signal domain a
+ Clash.Signal.Internal: register# :: forall dom a. (KnownDomain dom, NFDataX a) => Clock dom -> Reset dom -> Enable dom -> a -> a -> Signal dom a -> Signal dom a
- Clash.Signal.Internal: sample :: (Foldable f, NFData a) => f a -> [a]
+ Clash.Signal.Internal: sample :: (Foldable f, NFDataX a) => f a -> [a]
- Clash.Signal.Internal: sampleN :: (Foldable f, NFData a) => Int -> f a -> [a]
+ Clash.Signal.Internal: sampleN :: (Foldable f, NFDataX a) => Int -> f a -> [a]
- Clash.Signal.Internal: signal# :: a -> Signal domain a
+ Clash.Signal.Internal: signal# :: a -> Signal dom a
- Clash.Signal.Internal: simulate :: (NFData a, NFData b) => (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]
+ Clash.Signal.Internal: simulate :: (NFDataX a, NFDataX b) => (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
- Clash.Signal.Internal: simulate_lazy :: (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]
+ Clash.Signal.Internal: simulate_lazy :: (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]
- Clash.Signal.Internal: traverse# :: Applicative f => (a -> f b) -> Signal domain a -> f (Signal domain b)
+ Clash.Signal.Internal: traverse# :: Applicative f => (a -> f b) -> Signal dom a -> f (Signal dom b)
- Clash.Sized.BitVector: bLit :: KnownNat n => String -> Q (TExp (BitVector n))
+ Clash.Sized.BitVector: bLit :: forall n. KnownNat n => String -> Q (TExp (BitVector n))
- Clash.Sized.Fixed: Fixed :: rep (int + frac) -> Fixed
+ Clash.Sized.Fixed: Fixed :: rep (int + frac) -> Fixed (rep :: Nat -> *) (int :: Nat) (frac :: Nat)
- Clash.Sized.Fixed: [unFixed] :: Fixed -> rep (int + frac)
+ Clash.Sized.Fixed: [unFixed] :: Fixed (rep :: Nat -> *) (int :: Nat) (frac :: Nat) -> rep (int + frac)
- Clash.Sized.Fixed: divide :: DivideC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> Fixed rep (int1 + frac2 + 1) (int2 + frac1)
+ Clash.Sized.Fixed: divide :: DivideC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> Fixed rep ((int1 + frac2) + 1) (int2 + frac1)
- Clash.Sized.Fixed: type NumFixedC rep int frac = (SaturatingNum (rep (int + frac)), ExtendingNum (rep (int + frac)) (rep (int + frac)), MResult (rep (int + frac)) (rep (int + frac)) ~ rep ((int + int) + (frac + frac)), BitSize (rep ((int + int) + (frac + frac))) ~ (int + ((int + frac) + frac)), BitPack (rep ((int + int) + (frac + frac))), Bits (rep ((int + int) + (frac + frac))), KnownNat (BitSize (rep (int + frac))), BitPack (rep (int + frac)), Enum (rep (int + frac)), Bits (rep (int + frac)), Resize rep, KnownNat int, KnownNat frac)
+ Clash.Sized.Fixed: type NumFixedC rep int frac = (SaturatingNum (rep (int + frac)), ExtendingNum (rep (int + frac)) (rep (int + frac)), MResult (rep (int + frac)) (rep (int + frac)) ~ rep ((int + int) + (frac + frac)), BitSize (rep ((int + int) + (frac + frac))) ~ (int + ((int + frac) + frac)), BitPack (rep ((int + int) + (frac + frac))), Bits (rep ((int + int) + (frac + frac))), KnownNat (BitSize (rep (int + frac))), BitPack (rep (int + frac)), Enum (rep (int + frac)), Bits (rep (int + frac)), Ord (rep (int + frac)), Resize rep, KnownNat int, KnownNat frac)
- Clash.Sized.Internal.BitVector: BV :: Integer -> BitVector
+ Clash.Sized.Internal.BitVector: BV :: !Integer -> !Integer -> BitVector (n :: Nat)
- Clash.Sized.Internal.BitVector: Bit :: Integer -> Bit
+ Clash.Sized.Internal.BitVector: Bit :: !Integer -> !Integer -> Bit
- Clash.Sized.Internal.BitVector: [unsafeToInteger#] :: Bit -> Integer
+ Clash.Sized.Internal.BitVector: [unsafeToInteger#] :: Bit -> !Integer
- Clash.Sized.Internal.BitVector: [unsafeToInteger] :: BitVector -> Integer
+ Clash.Sized.Internal.BitVector: [unsafeToInteger] :: BitVector (n :: Nat) -> !Integer
- Clash.Sized.Internal.BitVector: bLit :: KnownNat n => String -> Q (TExp (BitVector n))
+ Clash.Sized.Internal.BitVector: bLit :: forall n. KnownNat n => String -> Q (TExp (BitVector n))
- Clash.Sized.Internal.BitVector: enumFromThenTo# :: BitVector n -> BitVector n -> BitVector n -> [BitVector n]
+ Clash.Sized.Internal.BitVector: enumFromThenTo# :: KnownNat n => BitVector n -> BitVector n -> BitVector n -> [BitVector n]
- Clash.Sized.Internal.BitVector: enumFromTo# :: BitVector n -> BitVector n -> [BitVector n]
+ Clash.Sized.Internal.BitVector: enumFromTo# :: KnownNat n => BitVector n -> BitVector n -> [BitVector n]
- Clash.Sized.Internal.BitVector: eq# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: eq# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: fromInteger# :: KnownNat n => Integer -> BitVector n
+ Clash.Sized.Internal.BitVector: fromInteger# :: KnownNat n => Integer -> Integer -> BitVector n
- Clash.Sized.Internal.BitVector: fromInteger## :: Integer -> Bit
+ Clash.Sized.Internal.BitVector: fromInteger## :: Integer -> Integer -> Bit
- Clash.Sized.Internal.BitVector: ge# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: ge# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: gt# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: gt# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: le# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: le# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: lt# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: lt# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: neq# :: BitVector n -> BitVector n -> Bool
+ Clash.Sized.Internal.BitVector: neq# :: KnownNat n => BitVector n -> BitVector n -> Bool
- Clash.Sized.Internal.BitVector: plus# :: BitVector m -> BitVector n -> BitVector (Max m n + 1)
+ Clash.Sized.Internal.BitVector: plus# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (Max m n + 1)
- Clash.Sized.Internal.BitVector: quot# :: BitVector n -> BitVector n -> BitVector n
+ Clash.Sized.Internal.BitVector: quot# :: KnownNat n => BitVector n -> BitVector n -> BitVector n
- Clash.Sized.Internal.BitVector: reduceOr# :: BitVector n -> Bit
+ Clash.Sized.Internal.BitVector: reduceOr# :: KnownNat n => BitVector n -> Bit
- Clash.Sized.Internal.BitVector: reduceXor# :: BitVector n -> Bit
+ Clash.Sized.Internal.BitVector: reduceXor# :: KnownNat n => BitVector n -> Bit
- Clash.Sized.Internal.BitVector: rem# :: BitVector n -> BitVector n -> BitVector n
+ Clash.Sized.Internal.BitVector: rem# :: KnownNat n => BitVector n -> BitVector n -> BitVector n
- Clash.Sized.Internal.BitVector: setSlice# :: BitVector (m + 1 + i) -> SNat m -> SNat n -> BitVector (m + 1 - n) -> BitVector (m + 1 + i)
+ Clash.Sized.Internal.BitVector: setSlice# :: BitVector ((m + 1) + i) -> SNat m -> SNat n -> BitVector ((m + 1) - n) -> BitVector ((m + 1) + i)
- Clash.Sized.Internal.BitVector: slice# :: BitVector (m + 1 + i) -> SNat m -> SNat n -> BitVector (m + 1 - n)
+ Clash.Sized.Internal.BitVector: slice# :: BitVector ((m + 1) + i) -> SNat m -> SNat n -> BitVector ((m + 1) - n)
- Clash.Sized.Internal.BitVector: times# :: BitVector m -> BitVector n -> BitVector (m + n)
+ Clash.Sized.Internal.BitVector: times# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (m + n)
- Clash.Sized.Internal.BitVector: toInteger# :: BitVector n -> Integer
+ Clash.Sized.Internal.BitVector: toInteger# :: KnownNat n => BitVector n -> Integer
- Clash.Sized.Internal.Index: I :: Integer -> Index
+ Clash.Sized.Internal.Index: I :: Integer -> Index (n :: Nat)
- Clash.Sized.Internal.Index: [unsafeToInteger] :: Index -> Integer
+ Clash.Sized.Internal.Index: [unsafeToInteger] :: Index (n :: Nat) -> Integer
- Clash.Sized.Internal.Index: eq# :: (Index n) -> (Index n) -> Bool
+ Clash.Sized.Internal.Index: eq# :: Index n -> Index n -> Bool
- Clash.Sized.Internal.Index: fromSNat :: (KnownNat m, CmpNat n m ~ 'LT) => SNat n -> Index m
+ Clash.Sized.Internal.Index: fromSNat :: (KnownNat m, CmpNat n m ~ 'LT) => SNat n -> Index m
- Clash.Sized.Internal.Index: minus# :: Index m -> Index n -> Index (m + n - 1)
+ Clash.Sized.Internal.Index: minus# :: Index m -> Index n -> Index ((m + n) - 1)
- Clash.Sized.Internal.Index: neq# :: (Index n) -> (Index n) -> Bool
+ Clash.Sized.Internal.Index: neq# :: Index n -> Index n -> Bool
- Clash.Sized.Internal.Index: plus# :: Index m -> Index n -> Index (m + n - 1)
+ Clash.Sized.Internal.Index: plus# :: Index m -> Index n -> Index ((m + n) - 1)
- Clash.Sized.Internal.Index: unpack# :: KnownNat n => BitVector (CLog 2 n) -> Index n
+ Clash.Sized.Internal.Index: unpack# :: (KnownNat n, 1 <= n) => BitVector (CLog 2 n) -> Index n
- Clash.Sized.Internal.Signed: S :: Integer -> Signed
+ Clash.Sized.Internal.Signed: S :: Integer -> Signed (n :: Nat)
- Clash.Sized.Internal.Signed: [unsafeToInteger] :: Signed -> Integer
+ Clash.Sized.Internal.Signed: [unsafeToInteger] :: Signed (n :: Nat) -> Integer
- Clash.Sized.Internal.Unsigned: U :: Integer -> Unsigned
+ Clash.Sized.Internal.Unsigned: U :: Integer -> Unsigned (n :: Nat)
- Clash.Sized.Internal.Unsigned: [unsafeToInteger] :: Unsigned -> Integer
+ Clash.Sized.Internal.Unsigned: [unsafeToInteger] :: Unsigned (n :: Nat) -> Integer
- Clash.Sized.Internal.Unsigned: unpack# :: BitVector n -> Unsigned n
+ Clash.Sized.Internal.Unsigned: unpack# :: KnownNat n => BitVector n -> Unsigned n
- Clash.Sized.RTree: data RTree :: Nat -> * -> *
+ Clash.Sized.RTree: data RTree :: Nat -> Type -> Type
- Clash.Sized.RTree: tdfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat * -> *) -> (a -> (p @@ 0)) -> (forall l. SNat l -> (p @@ l) -> (p @@ l) -> (p @@ (l + 1))) -> RTree k a -> (p @@ k)
+ Clash.Sized.RTree: tdfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat Type -> Type) -> (a -> p @@ 0) -> (forall l. SNat l -> (p @@ l) -> (p @@ l) -> p @@ (l + 1)) -> RTree k a -> p @@ k
- Clash.Sized.Vector: data VCons (a :: *) (f :: TyFun Nat *) :: *
+ Clash.Sized.Vector: data VCons (a :: Type) (f :: TyFun Nat Type) :: Type
- Clash.Sized.Vector: data Vec :: Nat -> * -> *
+ Clash.Sized.Vector: data Vec :: Nat -> Type -> Type
- Clash.Sized.Vector: dfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat * -> *) -> (forall l. SNat l -> a -> (p @@ l) -> (p @@ (l + 1))) -> (p @@ 0) -> Vec k a -> (p @@ k)
+ Clash.Sized.Vector: dfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat Type -> Type) -> (forall l. SNat l -> a -> (p @@ l) -> p @@ (l + 1)) -> (p @@ 0) -> Vec k a -> p @@ k
- Clash.Sized.Vector: dtfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat * -> *) -> (a -> (p @@ 0)) -> (forall l. SNat l -> (p @@ l) -> (p @@ l) -> (p @@ (l + 1))) -> Vec (2 ^ k) a -> (p @@ k)
+ Clash.Sized.Vector: dtfold :: forall p k a. KnownNat k => Proxy (p :: TyFun Nat Type -> Type) -> (a -> p @@ 0) -> (forall l. SNat l -> (p @@ l) -> (p @@ l) -> p @@ (l + 1)) -> Vec (2 ^ k) a -> p @@ k
- Clash.Sized.Vector: select :: (CmpNat (i + s) (s * n) ~ 'GT) => SNat f -> SNat s -> SNat n -> Vec (f + i) a -> Vec n a
+ Clash.Sized.Vector: select :: CmpNat (i + s) (s * n) ~ 'GT => SNat f -> SNat s -> SNat n -> Vec (f + i) a -> Vec n a
- Clash.Sized.Vector: selectI :: (CmpNat (i + s) (s * n) ~ 'GT, KnownNat n) => SNat f -> SNat s -> Vec (f + i) a -> Vec n a
+ Clash.Sized.Vector: selectI :: (CmpNat (i + s) (s * n) ~ 'GT, KnownNat n) => SNat f -> SNat s -> Vec (f + i) a -> Vec n a
- Clash.Sized.Vector: windows2d :: (KnownNat n, KnownNat m) => SNat (stY + 1) -> SNat (stX + 1) -> Vec ((stY + m) + 1) (Vec (stX + n + 1) a) -> Vec (m + 1) (Vec (n + 1) (Vec (stY + 1) (Vec (stX + 1) a)))
+ Clash.Sized.Vector: windows2d :: (KnownNat n, KnownNat m) => SNat (stY + 1) -> SNat (stX + 1) -> Vec ((stY + m) + 1) (Vec ((stX + n) + 1) a) -> Vec (m + 1) (Vec (n + 1) (Vec (stY + 1) (Vec (stX + 1) a)))
- Clash.XException: isX :: NFData a => a -> Either String a
+ Clash.XException: isX :: a -> Either String a
- Clash.Xilinx.ClockGen: clockWizard :: forall pllOut pllIn name. SSymbol name -> Clock pllIn 'Source -> Reset pllIn 'Asynchronous -> (Clock pllOut 'Source, Signal pllOut Bool)
+ Clash.Xilinx.ClockGen: clockWizard :: forall domIn domOut periodIn periodOut edge init polarity name. (KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity), KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity)) => SSymbol name -> Clock domIn -> Reset domIn -> (Clock domOut, Enable domOut)
- Clash.Xilinx.ClockGen: clockWizardDifferential :: forall pllOut pllIn name. SSymbol name -> Clock pllIn 'Source -> Clock pllIn 'Source -> Reset pllIn 'Asynchronous -> (Clock pllOut 'Source, Signal pllOut Bool)
+ Clash.Xilinx.ClockGen: clockWizardDifferential :: forall domIn domOut periodIn periodOut edge init polarity name. (KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity), KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity)) => SSymbol name -> Clock domIn -> Clock domIn -> Reset domIn -> (Clock domOut, Enable domOut)
- Clash.Xilinx.DDR: iddr :: (HasCallStack, fast ~ 'Dom n pFast, slow ~ 'Dom n (2 * pFast), KnownNat m) => Clock slow gated -> Reset slow synchronous -> Signal fast (BitVector m) -> Signal slow ((BitVector m), (BitVector m))
+ Clash.Xilinx.DDR: iddr :: (HasCallStack, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity), KnownNat m) => Clock slow -> Reset slow -> Enable slow -> Signal fast (BitVector m) -> Signal slow (BitVector m, BitVector m)
- Clash.Xilinx.DDR: oddr :: (slow ~ 'Dom n (2 * pFast), fast ~ 'Dom n pFast, KnownNat m) => Clock slow gated -> Reset slow synchronous -> Signal slow (BitVector m, BitVector m) -> Signal fast (BitVector m)
+ Clash.Xilinx.DDR: oddr :: (KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity), KnownConfiguration slow ('DomainConfiguration slow (2 * fPeriod) edge reset init polarity), KnownNat m) => Clock slow -> Reset slow -> Enable slow -> Signal slow (BitVector m, BitVector m) -> Signal fast (BitVector m)

Files

CHANGELOG.md view
@@ -1,5 +1,130 @@ # Changelog for [`clash-prelude` package](http://hackage.haskell.org/package/clash-prelude) +## 1.0.0 *September 3rd 2019*+* New features:+  * API changes: check the migration guide at the end of `Clash.Tutorial`+  * All memory elements now have an (implicit) enable line; "Gated" clocks have+    been removed as the clock wasn't actually gated, but implemented as an+    enable line.+  * Circuit domains are now configurable in:+    * (old) The clock period+    * (new) Clock edge on which memory elements latch their inputs+      (rising edge or falling edge)+    * (new) Whether the reset port of a memory element is level sensitive+      (asynchronous reset) or edge sensitive (synchronous reset)+    * (new) Whether the reset port of a memory element is active-high or+      active-low (negated reset)+    * (new) Whether memory element power on in a configurable/defined state+      (common on FPGAs) or in an undefined state (ASICs)++    * See the [blog post](https://clash-lang.org/blog/0005-synthesis-domain/) on this new feature+  * Data types can now be given custom bit-representations: http://hackage.haskell.org/package/clash-prelude/docs/Clash-Annotations-BitRepresentation.html+  * Annotate expressions with attributes that persist in the generated HDL,+    e.g. synthesis directives: http://hackage.haskell.org/package/clash-prelude/docs/Clash-Annotations-SynthesisAttributes.html+  * Control (System)Verilog module instance, and VHDL entity instantiation names+    in generated code: http://hackage.haskell.org/package/clash-prelude/docs/Clash-Magic.html+  * Much improved infrastructure for handling of unknown values: defined spine,+    but unknown leafs: http://hackage.haskell.org/package/clash-prelude/docs/Clash-XException.html#t:NFDataX+  * Experimental: Multiple hidden clocks. Can be enabled by compiling+    `clash-prelude` with `-fmultiple-hidden`+  * Experimental: Limited GADT support (pattern matching on vectors, or custom+    GADTs as longs as their usage can be statically removed; no support of+    recursive GADTs)+  * Experimental: Use regular Haskell functions to generate HDL black boxes for+    primitives (in an addition to existing string templates for HDL black boxes)+    See for example: http://hackage.haskell.org/package/clash-lib/docs/Clash-Primitives-Intel-ClockGen.html++* Fixes issues:+  * [#316](https://github.com/clash-lang/clash-prelude/issues/316)+  * [#319](https://github.com/clash-lang/clash-prelude/issues/319)+  * [#323](https://github.com/clash-lang/clash-prelude/issues/323)+  * [#324](https://github.com/clash-lang/clash-prelude/issues/324)+  * [#329](https://github.com/clash-lang/clash-prelude/issues/329)+  * [#331](https://github.com/clash-lang/clash-prelude/issues/331)+  * [#332](https://github.com/clash-lang/clash-prelude/issues/332)+  * [#335](https://github.com/clash-lang/clash-prelude/issues/335)+  * [#348](https://github.com/clash-lang/clash-prelude/issues/348)+  * [#349](https://github.com/clash-lang/clash-prelude/issues/349)+  * [#350](https://github.com/clash-lang/clash-prelude/issues/350)+  * [#351](https://github.com/clash-lang/clash-prelude/issues/351)+  * [#352](https://github.com/clash-lang/clash-prelude/issues/352)+  * [#353](https://github.com/clash-lang/clash-prelude/issues/353)+  * [#358](https://github.com/clash-lang/clash-prelude/issues/358)+  * [#359](https://github.com/clash-lang/clash-prelude/issues/359)+  * [#363](https://github.com/clash-lang/clash-prelude/issues/363)+  * [#364](https://github.com/clash-lang/clash-prelude/issues/364)+  * [#365](https://github.com/clash-lang/clash-prelude/issues/365)+  * [#371](https://github.com/clash-lang/clash-prelude/issues/371)+  * [#372](https://github.com/clash-lang/clash-prelude/issues/372)+  * [#373](https://github.com/clash-lang/clash-prelude/issues/373)+  * [#378](https://github.com/clash-lang/clash-prelude/issues/378)+  * [#380](https://github.com/clash-lang/clash-prelude/issues/380)+  * [#381](https://github.com/clash-lang/clash-prelude/issues/381)+  * [#382](https://github.com/clash-lang/clash-prelude/issues/382)+  * [#383](https://github.com/clash-lang/clash-prelude/issues/383)+  * [#387](https://github.com/clash-lang/clash-prelude/issues/387)+  * [#393](https://github.com/clash-lang/clash-prelude/issues/393)+  * [#396](https://github.com/clash-lang/clash-prelude/issues/396)+  * [#398](https://github.com/clash-lang/clash-prelude/issues/398)+  * [#399](https://github.com/clash-lang/clash-prelude/issues/399)+  * [#401](https://github.com/clash-lang/clash-prelude/issues/401)+  * [#403](https://github.com/clash-lang/clash-prelude/issues/403)+  * [#407](https://github.com/clash-lang/clash-prelude/issues/407)+  * [#412](https://github.com/clash-lang/clash-prelude/issues/412)+  * [#413](https://github.com/clash-lang/clash-prelude/issues/413)+  * [#420](https://github.com/clash-lang/clash-prelude/issues/420)+  * [#422](https://github.com/clash-lang/clash-prelude/issues/422)+  * [#423](https://github.com/clash-lang/clash-prelude/issues/423)+  * [#424](https://github.com/clash-lang/clash-prelude/issues/424)+  * [#438](https://github.com/clash-lang/clash-prelude/issues/438)+  * [#450](https://github.com/clash-lang/clash-prelude/issues/450)+  * [#452](https://github.com/clash-lang/clash-prelude/issues/452)+  * [#455](https://github.com/clash-lang/clash-prelude/issues/455)+  * [#460](https://github.com/clash-lang/clash-prelude/issues/460)+  * [#461](https://github.com/clash-lang/clash-prelude/issues/461)+  * [#463](https://github.com/clash-lang/clash-prelude/issues/463)+  * [#468](https://github.com/clash-lang/clash-prelude/issues/468)+  * [#475](https://github.com/clash-lang/clash-prelude/issues/475)+  * [#476](https://github.com/clash-lang/clash-prelude/issues/476)+  * [#500](https://github.com/clash-lang/clash-prelude/issues/500)+  * [#507](https://github.com/clash-lang/clash-prelude/issues/507)+  * [#512](https://github.com/clash-lang/clash-prelude/issues/512)+  * [#516](https://github.com/clash-lang/clash-prelude/issues/516)+  * [#517](https://github.com/clash-lang/clash-prelude/issues/517)+  * [#526](https://github.com/clash-lang/clash-prelude/issues/526)+  * [#556](https://github.com/clash-lang/clash-prelude/issues/556)+  * [#560](https://github.com/clash-lang/clash-prelude/issues/560)+  * [#566](https://github.com/clash-lang/clash-prelude/issues/566)+  * [#567](https://github.com/clash-lang/clash-prelude/issues/567)+  * [#569](https://github.com/clash-lang/clash-prelude/issues/569)+  * [#573](https://github.com/clash-lang/clash-prelude/issues/573)+  * [#575](https://github.com/clash-lang/clash-prelude/issues/575)+  * [#581](https://github.com/clash-lang/clash-prelude/issues/581)+  * [#582](https://github.com/clash-lang/clash-prelude/issues/582)+  * [#586](https://github.com/clash-lang/clash-prelude/issues/586)+  * [#588](https://github.com/clash-lang/clash-prelude/issues/588)+  * [#591](https://github.com/clash-lang/clash-prelude/issues/591)+  * [#596](https://github.com/clash-lang/clash-prelude/issues/596)+  * [#601](https://github.com/clash-lang/clash-prelude/issues/601)+  * [#607](https://github.com/clash-lang/clash-prelude/issues/607)+  * [#629](https://github.com/clash-lang/clash-prelude/issues/629)+  * [#637](https://github.com/clash-lang/clash-prelude/issues/637)+  * [#644](https://github.com/clash-lang/clash-prelude/issues/644)+  * [#647](https://github.com/clash-lang/clash-prelude/issues/647)+  * [#661](https://github.com/clash-lang/clash-prelude/issues/661)+  * [#668](https://github.com/clash-lang/clash-prelude/issues/668)+  * [#677](https://github.com/clash-lang/clash-prelude/issues/677)+  * [#678](https://github.com/clash-lang/clash-prelude/issues/678)+  * [#682](https://github.com/clash-lang/clash-prelude/issues/682)+  * [#691](https://github.com/clash-lang/clash-prelude/issues/691)+  * [#703](https://github.com/clash-lang/clash-prelude/issues/703)+  * [#713](https://github.com/clash-lang/clash-prelude/issues/713)+  * [#715](https://github.com/clash-lang/clash-prelude/issues/715)+  * [#727](https://github.com/clash-lang/clash-prelude/issues/727)+  * [#730](https://github.com/clash-lang/clash-prelude/issues/730)+  * [#736](https://github.com/clash-lang/clash-prelude/issues/736)+  * [#738](https://github.com/clash-lang/clash-prelude/issues/738)+ ## 0.99.3 *July 26th 2018* * Bundle and BitPack instances up to and including 62-tuples * Handle undefined writes to RAM properly@@ -174,7 +299,7 @@   This is needed, because `assert` now reports the clock cycle, and clock domain, when an assertion fails.   * `defClkAltera` and `defClkXilinx` are replaced by, `altpll` and `alteraPll` for Altera clock sources, and `clockWizard` for Xilinx clock sources.   These names correspond to the names of the generator utilities in Quartus and ISE/Vivado.-  * Add [Safe](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe-haskell.html) versions of the prelude modules: `CLaSH.Prelude.Safe` and `CLaSH.Prelude.Explicit.Safe`+  * Add [Safe](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe_haskell.html) versions of the prelude modules: `CLaSH.Prelude.Safe` and `CLaSH.Prelude.Explicit.Safe`   * Add synchronizers in the `CLaSH.Prelude.Synchronizer` module  ## 0.8 *June 3rd 2015*
LICENSE view
@@ -1,6 +1,6 @@ Copyright (c) 2013-2016, University of Twente,-              2016-2017, Myrtle Software Ltd,-              2017     , QBayLogic, Google Inc.+              2016-2019, Myrtle Software Ltd,+              2017-2019, QBayLogic B.V., Google Inc. All rights reserved.  Redistribution and use in source and binary forms, with or without
README.md view
@@ -1,18 +1,15 @@-# CλaSH - A functional hardware description language+# Clash - A functional hardware description language -[![Build Status](https://travis-ci.org/clash-lang/clash-prelude.svg?branch=master)](https://travis-ci.org/clash-lang/clash-prelude)+[![Pipeline status](https://gitlab.com/clash-lang/clash-compiler/badges/master/pipeline.svg)](https://gitlab.com/clash-lang/clash-compiler/commits/master) [![Hackage](https://img.shields.io/hackage/v/clash-prelude.svg)](https://hackage.haskell.org/package/clash-prelude) [![Hackage Dependencies](https://img.shields.io/hackage-deps/v/clash-prelude.svg?style=flat)](http://packdeps.haskellers.com/feed?needle=exact%3Aclash-prelude) -__WARNING__-Only works with GHC-8.2 or higher (http://www.haskell.org/ghc/download_ghc_8_4_3)!--CλaSH (pronounced ‘clash’) is a functional hardware description language that-borrows both its syntax and semantics from the functional programming language-Haskell. The CλaSH compiler transforms these high-level descriptions to+Clash is a functional hardware description language that borrows both+its syntax and semantics from the functional programming language+Haskell. The Clash compiler transforms these high-level descriptions to low-level synthesizable VHDL, Verilog, or SystemVerilog. -Features of CλaSH:+Features of Clash:    * Strongly typed, yet with a very high degree of type inference, enabling both     safe and fast prototyping using concise descriptions.
benchmarks/BenchBitVector.hs view
@@ -70,21 +70,21 @@   where     setup = return (smallValue1,smallValue2) -boundedPlusBench :: Benchmark-boundedPlusBench = env setup $ \m ->-  bench "boundedPlus WORD_SIZE_IN_BITS" $ nf (uncurry (boundedPlus)) m+boundedAddBench :: Benchmark+boundedAddBench = env setup $ \m ->+  bench "boundedAdd WORD_SIZE_IN_BITS" $ nf (uncurry (boundedAdd)) m   where     setup = return (smallValue1,smallValue2) -boundedMinBench :: Benchmark-boundedMinBench = env setup $ \m ->-  bench "boundedMin WORD_SIZE_IN_BITS" $ nf (uncurry (boundedMin)) m+boundedSubBench :: Benchmark+boundedSubBench = env setup $ \m ->+  bench "boundedSub WORD_SIZE_IN_BITS" $ nf (uncurry (boundedSub)) m   where     setup = return (smallValue1,smallValue2) -boundedMultBench :: Benchmark-boundedMultBench = env setup $ \m ->-  bench "boundedMult WORD_SIZE_IN_BITS" $ nf (uncurry (boundedMult)) m+boundedMulBench :: Benchmark+boundedMulBench = env setup $ \m ->+  bench "boundedMul WORD_SIZE_IN_BITS" $ nf (uncurry (boundedMul)) m   where     setup = return (smallValue1,smallValue2) 
benchmarks/BenchFixed.hs view
@@ -50,6 +50,6 @@  multBench_wrap :: Benchmark multBench_wrap = env setup $ \m ->-  bench "satMult SatWrap" $ nf (uncurry (satMult SatWrap)) m+  bench "satMult SatWrap" $ nf (uncurry (satMul SatWrap)) m   where     setup = return (smallValueU1,smallValueU2)
benchmarks/benchmark-main.hs view
@@ -18,9 +18,9 @@         , BV.plusBench         , BV.minusBench         , BV.timesBench-        , BV.boundedPlusBench-        , BV.boundedMinBench-        , BV.boundedMultBench+        , BV.boundedAddBench+        , BV.boundedSubBench+        , BV.boundedMulBench         , BV.msbBench         , BV.msbBenchL         , BV.appendBench
clash-prelude.cabal view
@@ -1,13 +1,13 @@ Name:                 clash-prelude-Version:              0.99.3+Version:              1.0.0 Synopsis:             CAES Language for Synchronous Hardware - Prelude library Description:-  CλaSH (pronounced ‘clash’) is a functional hardware description language that-  borrows both its syntax and semantics from the functional programming language-  Haskell. The CλaSH compiler transforms these high-level descriptions to-  low-level synthesizable VHDL, Verilog, or SystemVerilog.+  Clash is a functional hardware description language that borrows both its+  syntax and semantics from the functional programming language Haskell. The+  Clash compiler transforms these high-level descriptions to low-level+  synthesizable VHDL, Verilog, or SystemVerilog.   .-  Features of CλaSH:+  Features of Clash:   .   * Strongly typed, but with a very high degree of type inference, enabling both     safe and fast prototyping using concise descriptions.@@ -45,11 +45,11 @@ bug-reports:          http://github.com/clash-lang/clash-prelude/issues License:              BSD2 License-file:         LICENSE-Author:               Christiaan Baaij-Maintainer:           Christiaan Baaij <christiaan.baaij@gmail.com>+Author:               The Clash Authors+Maintainer:           QBayLogic B.V. <devops@qbaylogic.com> Copyright:            Copyright © 2013-2016, University of Twente,                                   2016-2017, Myrtle Software Ltd,-                                  2017     , QBayLogic, Google Inc.+                                  2017-2019, QBayLogic B.V., Google Inc. Category:             Hardware Build-type:           Simple @@ -59,19 +59,43 @@  extra-doc-files:      doc/*.svg -Cabal-version:        1.18-Tested-with:          GHC == 8.2.2, GHC == 8.4.1, GHC == 8.5+Cabal-version:        >=1.18+Tested-with:          GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.1  source-repository head   type: git   location: https://github.com/clash-lang/clash-prelude.git +flag super-strict+  description:+    Use `deepseqX` (instead of `seqX`) in register-like constructs. This can+    help to eliminate space leaks when using lazy data structures in+    registers-like constructs. This potentially slows down Clash hardware+    simulation.+  default: False+  manual: True++flag multiple-hidden+  description:+    Allow multiple hidden clocks, resets, and enables to be used. This is an+    experimental feature, possibly triggering confusing error messages. By+    default, it is enabled on development versions of Clash and disabled on+    releases.+  default: False+  manual: True+ flag doctests   description:     You can disable testing with doctests using `-f-doctests`.   default: True   manual: True +flag unittests+  description:+    You can disable testing with unittests using `-f-unittests`.+  default: True+  manual: True+ flag benchmarks   description:     You can disable testing with benchmarks using `-f-benchmarks`.@@ -83,14 +107,38 @@    default-language:   Haskell2010   ghc-options:        -Wall -fexpose-all-unfoldings -fno-worker-wrapper+  CPP-Options:        -DCABAL +  if flag(super-strict)+    CPP-Options: -DCLASH_SUPER_STRICT++  if flag(multiple-hidden)+    CPP-Options: -DCLASH_MULTIPLE_HIDDEN++  if flag(multiple-hidden)+    Exposed-modules:  Clash.Prelude.Synchronizer+   Exposed-modules:    Clash.Annotations.TopEntity                       Clash.Annotations.Primitive+                      Clash.Annotations.BitRepresentation+                      Clash.Annotations.BitRepresentation.Deriving+                      Clash.Annotations.BitRepresentation.Internal+                      Clash.Annotations.BitRepresentation.Util+                      Clash.Annotations.SynthesisAttributes                        Clash.Class.BitPack+                      Clash.Class.Exp+                      Clash.Class.HasDomain+                      Clash.Class.HasDomain.HasSingleDomain+                      Clash.Class.HasDomain.HasSpecificDomain+                      Clash.Class.HasDomain.CodeGen+                      Clash.Class.HasDomain.Common                       Clash.Class.Num                       Clash.Class.Resize +                      Clash.Clocks+                      Clash.Clocks.Deriving+                       Clash.Explicit.BlockRam                       Clash.Explicit.BlockRam.File                       Clash.Explicit.DDR@@ -106,11 +154,15 @@                       Clash.Explicit.Synchronizer                       Clash.Explicit.Testbench +                      Clash.HaskellPrelude+                       Clash.Hidden                        Clash.Intel.ClockGen                       Clash.Intel.DDR +                      Clash.Magic+                       Clash.NamedTypes                        Clash.Prelude@@ -135,8 +187,13 @@                        Clash.Signal                       Clash.Signal.Bundle+                      Clash.Signal.BiSignal                       Clash.Signal.Delayed+                      Clash.Signal.Delayed.Internal+                      Clash.Signal.Delayed.Bundle                       Clash.Signal.Internal+                      Clash.Signal.Internal.Ambiguous+                      Clash.Signal.Trace                        Clash.Sized.BitVector                       Clash.Sized.Fixed@@ -160,7 +217,10 @@                       Clash.Examples    other-modules:      Clash.Class.BitPack.Internal+                      Clash.CPP                       Clash.Signal.Bundle.Internal+                      Language.Haskell.TH.Compat+                      Paths_clash_prelude    other-extensions:   CPP                       BangPatterns@@ -191,57 +251,97 @@                       ViewPatterns    Build-depends:      array                     >= 0.5.1.0 && < 0.6,-                      base                      >= 4.8.0.0 && < 5,+                      base                      >= 4.10    && < 5,                       bifunctors                >= 5.4.0   && < 6.0,-                      constraints               >= 0.8     && < 1.0,+                      binary                    >= 0.8.5   && < 0.11,+                      bytestring                >= 0.10.8  && < 0.11,+                      constraints               >= 0.9     && < 1.0,+                      containers                >= 0.4.0   && < 0.7,                       data-binary-ieee754       >= 0.4.4   && < 0.6,-                      data-default              >= 0.5.3   && < 0.8,+                      data-default-class        >= 0.1.2   && < 0.2,                       integer-gmp               >= 0.5.1.0 && < 1.1,                       deepseq                   >= 1.4.1.0 && < 1.5,-                      ghc-prim                  >= 0.3.1.0 && < 0.6,-                      ghc-typelits-extra        >= 0.2.5   && < 0.3,-                      ghc-typelits-knownnat     >= 0.5     && < 0.6,-                      ghc-typelits-natnormalise >= 0.6     && < 0.7,+                      ghc-prim                  >= 0.5.1.0 && < 0.6,+                      ghc-typelits-extra        >= 0.3.1   && < 0.4,+                      ghc-typelits-knownnat     >= 0.6     && < 0.8,+                      ghc-typelits-natnormalise >= 0.6     && < 0.8,+                      hashable                  >= 1.2.1.0  && < 1.4,                       half                      >= 0.2.2.3 && < 1.0,-                      lens                      >= 4.9     && < 4.18,-                      QuickCheck                >= 2.7     && < 2.12,+                      lens                      >= 4.9     && < 4.19,+                      QuickCheck                >= 2.7     && < 2.14,                       reflection                >= 2       && < 2.2,                       singletons                >= 1.0     && < 3.0,-                      template-haskell          >= 2.12.0.0 && < 2.14,-                      transformers              >= 0.4.2.0 && < 0.6,+                      template-haskell          >= 2.12.0.0 && < 2.16,+                      th-lift                   >= 0.7.0    && < 0.9,+                      th-orphans                >= 0.13.1   && < 1.0,+                      text                      >= 0.11.3.1 && < 1.3,+                      time                      >= 1.8     && < 1.10,+                      transformers              >= 0.5.2.0 && < 0.6,+                      type-errors               >= 0.2.0.0 && < 0.3,                       vector                    >= 0.11    && < 1.0  test-suite doctests   type:             exitcode-stdio-1.0   default-language: Haskell2010   main-is:          doctests.hs-  ghc-options:      -Wall+  ghc-options:      -Wall -threaded   hs-source-dirs:   tests    if !flag(doctests)     buildable: False   else     build-depends:-      base    >= 4     && < 5,+      base,       doctest >= 0.9.1 && < 0.17,       clash-prelude+  if impl(ghc >= 8.6)+    build-depends:+      doctest >= 0.16.1 +test-suite unittests+  type:             exitcode-stdio-1.0+  default-language: Haskell2010+  main-is:          unittests.hs+  ghc-options:      -Wall+  hs-source-dirs:   tests++  if !flag(unittests)+    buildable: False+  else+    build-depends:+      clash-prelude,++      ghc-typelits-knownnat,++      base,+      hint          >= 0.7      && < 0.10,+      tasty         >= 1.2      && < 1.3,+      tasty-hunit++  Other-Modules: Clash.Tests.BitPack+                 Clash.Tests.BitVector+                 Clash.Tests.DerivingDataRepr+                 Clash.Tests.DerivingDataReprTypes+                 Clash.Tests.Signal+                 Clash.Tests.NFDataX++ benchmark benchmark-clash-prelude   type:             exitcode-stdio-1.0   default-language: Haskell2010   main-is:          benchmark-main.hs-  ghc-options:      -Wall+  ghc-options:      -O2 -Wall   hs-source-dirs:   benchmarks    if !flag(benchmarks)     buildable: False   else     build-depends:-      base              >= 4       && < 5,+      base,       clash-prelude,       criterion         >= 1.3.0.0 && < 1.6,-      deepseq           >= 1.4.0.1 && < 1.5,-      template-haskell  >= 2.9.0.0 && < 2.14+      deepseq,+      template-haskell    Other-Modules:    BenchBitVector                     BenchFixed
+ src/Clash/Annotations/BitRepresentation.hs view
@@ -0,0 +1,130 @@+{-|+Copyright  :  (C) 2018, Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++Using /ANN/ pragma's you can tell the Clash compiler to use a custom+bit representation for a data type. See @DataReprAnn@ for documentation.++-}++{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DeriveLift         #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell    #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Clash.Annotations.BitRepresentation+ (+ -- * Data structures to express a custom bit representation+   DataReprAnn(..)+ , ConstrRepr(..)+ -- * Convenience type synonyms for Integer+ , BitMask+ , Value+ , Size+ , FieldAnn++ -- * Functions+ , liftQ+ ) where++import           Data.Data                  (Data)+import           Data.Typeable              (Typeable)+import           Language.Haskell.TH.Instances ()+import qualified Language.Haskell.TH.Lift   ()+import qualified Language.Haskell.TH.Syntax as TH+import           GHC.Generics               (Generic)++type BitMask  = Integer+type Value    = Integer+type Size     = Int++type FieldAnn = BitMask++-- | Lift values inside of 'TH.Q' to a Template Haskell expression+liftQ :: TH.Lift a => TH.Q a -> TH.Q TH.Exp+liftQ = (>>= TH.lift)++-- NOTE: The following instances are imported from Language.Haskell.TH.Lift.+-- This module also implements 'instance Lift Exp', which might make debugging+-- template haskell more difficult. Please uncomment these instances and the+-- import of TH.Lift whenever it suits you.+--+--deriving instance TH.Lift TH.Name+--deriving instance TH.Lift TH.OccName+--deriving instance TH.Lift TH.NameFlavour+--deriving instance TH.Lift TH.ModName+--deriving instance TH.Lift TH.NameSpace+--deriving instance TH.Lift TH.PkgName+++-- | Annotation for custom bit representations of data types+--+-- Using /ANN/ pragma's you can tell the Clash compiler to use a custom+-- bit-representation for a data type.+--+-- For example:+--+-- @+-- data Color = R | G | B+-- {-# ANN module (DataReprAnn+--                   $(liftQ [t|Color|])+--                   2+--                   [ ConstrRepr 'R 0b11 0b00 []+--                   , ConstrRepr 'G 0b11 0b01 []+--                   , ConstrRepr 'B 0b11 0b10 []+--                   ]) #-}+-- @+--+-- This specifies that @R@ should be encoded as 0b00, @G@ as 0b01, and+-- @B@ as 0b10. The first binary value in every @ConstrRepr@ in this example+-- is a mask, indicating which bits in the data type are relevant. In this case+-- all of the bits are.+--+-- Or if we want to annotate @Maybe Color@:+--+-- @+-- {-# ANN module ( DataReprAnn+--                    $(liftQ [t|Maybe Color|])+--                    2+--                    [ ConstrRepr 'Nothing 0b11 0b11 []+--                    , ConstrRepr 'Just 0b00 0b00 [0b11]+--                    ] ) #-}+-- @+--+-- By default, @Maybe Color@ is a data type which consumes 3 bits. A single bit+-- to indicate the constructor (either @Just@ or @Nothing@), and two bits to encode+-- the first field of @Just@. Notice that we saved a single bit by exploiting+-- the fact that @Color@ only uses three values (0, 1, 2), but takes two bits+-- to encode it. We can therefore use the last - unused - value (3), to encode+-- one of the constructors of @Maybe@. We indicate which bits encode the+-- underlying @Color@ field of @Just@ by passing /[0b11]/ to ConstrRepr. This+-- indicates that the first field is encoded in the first and second bit of the+-- whole datatype (0b11).+data DataReprAnn =+  DataReprAnn+    -- Type this annotation is for:+    TH.Type+    -- Size of type:+    Size+    -- Constructors:+    [ConstrRepr]+      deriving (Show, Data, Typeable, Eq, Generic, TH.Lift)++-- | Annotation for constructors. Indicates how to match this constructor based+-- off of the whole datatype.+data ConstrRepr =+  ConstrRepr+    -- Constructor name:+    TH.Name+    -- Bits relevant for this constructor:+    BitMask+    -- data & mask should be equal to..:+    Value+    -- Masks for fields. Indicates where fields are stored:+    [FieldAnn]+      deriving (Show, Data, Typeable, Eq, Generic, TH.Lift)
+ src/Clash/Annotations/BitRepresentation/Deriving.hs view
@@ -0,0 +1,928 @@+{-|+Copyright  :  (C) 2018, Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++This module contains:++  * Template Haskell functions for deriving 'BitPack' instances given a+    custom bit representation as those defined in+    "Clash.Annotations.BitRepresentation".++  * Template Haskell functions for deriving custom bit representations,+    e.g. one-hot, for a data type.++-}+{-# LANGUAGE CPP                #-}+{-# LANGUAGE DataKinds          #-}+{-# LANGUAGE DeriveAnyClass     #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DeriveLift         #-}+{-# LANGUAGE LambdaCase         #-}+{-# LANGUAGE MagicHash          #-}+{-# LANGUAGE MultiWayIf         #-}+{-# LANGUAGE QuasiQuotes        #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell    #-}+{-# LANGUAGE ViewPatterns       #-}++-- See: https://ghc.haskell.org/trac/ghc/ticket/14959. TODO: Consider putting+-- the offending function (bitsToInteger') in a separate module.+{-# OPTIONS_GHC -O0 #-}++module Clash.Annotations.BitRepresentation.Deriving+  (+  -- * Derivation functions+    deriveAnnotation+  , deriveBitPack+  , deriveDefaultAnnotation+  , derivePackedAnnotation+  , derivePackedMaybeAnnotation+  , deriveBlueSpecAnnotation+  -- * Derivators+  , defaultDerivator+  , blueSpecDerivator+  , packedDerivator+  , packedMaybeDerivator+  , simpleDerivator+  -- * Util functions+  , dontApplyInHDL+  -- * Types associated with various functions+  , ConstructorType(..)+  , FieldsType(..)+  -- * Convenience type synonyms+  , Derivator+  , DataReprAnnExp+  ) where++import Clash.Annotations.BitRepresentation+  (DataReprAnn(..), ConstrRepr(..), BitMask, Value, Size, liftQ)+import Clash.Annotations.BitRepresentation.Internal+  (dataReprAnnToDataRepr', constrReprToConstrRepr', DataRepr'(..))+import Clash.Annotations.BitRepresentation.Util+  (bitOrigins, bitOrigins', BitOrigin(..), bitRanges, Bit)+import qualified Clash.Annotations.BitRepresentation.Util+  as Util++import           Clash.Class.BitPack+  (BitPack, BitSize, pack, packXWith, unpack)+import           Clash.Class.Resize         (resize)+import           Language.Haskell.TH.Compat (mkTySynInstD)+import           Clash.Sized.BitVector      (BitVector, low, (++#))+import           Clash.Sized.Internal.BitVector (undefined#)+import           Control.DeepSeq            (NFData)+import           Control.Monad              (forM)+import           Data.Bits+  (shiftL, shiftR, complement, (.&.), (.|.), zeroBits, popCount, bit, testBit,+   Bits, setBit)+import           Data.Data                  (Data)+import           Data.List+  (mapAccumL, zipWith4, sortOn, partition)+import           Data.Typeable              (Typeable)+import qualified Data.Map                   as Map+import           Data.Maybe                 (fromMaybe)+import qualified Data.Set                   as Set+import           Data.Proxy                 (Proxy(..))+import           GHC.Exts                   (Int(I#))+import           GHC.Generics               (Generic)+import           GHC.Integer.Logarithms     (integerLog2#)+import           GHC.TypeLits               (natVal)+import           Language.Haskell.TH+import           Language.Haskell.TH.Syntax++-- | Used to track constructor bits in packed derivation+data BitMaskOrigin+  = External+  -- ^ Constructor bit should be stored externally+  | Embedded BitMask Value+  -- ^ Constructor bit should be stored in one of the constructor's fields+    deriving (Show, Data, Typeable, Lift)++isExternal :: BitMaskOrigin -> Bool+isExternal External = True+isExternal _        = False++type ReprAnnCache = Map.Map Type DataReprAnn++type NameMap = Map.Map Name Type++-- | DataReprAnn as template haskell expression+type DataReprAnnExp = Exp++-- | A derivator derives a bit representation given a type+type Derivator = Type -> Q DataReprAnnExp++-- | Indicates how to pack constructor for simpleDerivator+data ConstructorType+  = Binary+  -- ^ First constructor will be encoded as 0b0, the second as 0b1, the third+  -- as 0b10, etc.+  | OneHot+  -- ^ Reserve a single bit for each constructor marker.++-- | Indicates how to pack (constructor) fields for simpleDerivator+data FieldsType+  = OverlapL+  -- ^ Store fields of different constructors at (possibly) overlapping bit+  -- positions. That is, a data type with two constructors with each two fields+  -- of each one bit will take /two/ bits for its whole representation (plus+  -- constructor bits). Overlap is left-biased, i.e. don't care bits are padded+  -- to the right.+  --+  -- This is the default behavior of Clash.+  | OverlapR+  -- ^ Store fields of different constructors at (possibly) overlapping bit+  -- positions. That is, a data type with two constructors with each two fields+  -- of each one bit will take /two/ bits for its whole representation (plus+  -- constructor bits). Overlap is right biased, i.e. don't care bits are padded+  -- between between the constructor bits and the field bits.+  | Wide+  -- ^ Store fields of different constructs at non-overlapping positions. That+  -- is, a data type with two constructors with each two fields of each one bit+  -- will take /four/ bits for its whole representation (plus constructor bits).++-- | Determine most significant bit set for given integer.+--+-- TODO: Current complexity is O(n). We could probably use machine instructions+-- for ~constant complexity.+msb :: Integer -> Int+msb 0 = error $ "Most significant bit does not exist for zero."+msb 1 = 0+msb n = 1 + msb (shiftR n 1)++mkReprAnnCache :: [DataReprAnn] -> ReprAnnCache+mkReprAnnCache anns =+  Map.fromList [(typ, rAnn) | rAnn@(DataReprAnn typ _ _) <- anns]++-- | Integer version of (ceil . log2). Can handle arguments up to 2^(2^WORDWIDTH).+integerLog2Ceil :: Integer -> Int+integerLog2Ceil n =+  let nlog2 = fromIntegral $ I# (integerLog2# n) in+  if n > 2^nlog2 then nlog2 + 1 else nlog2++-- | Determine number of bits needed to represent /n/ options. Alias for+-- integerLog2Ceil to increase readability of programmer intentention.+bitsNeeded :: Integer -> Int+bitsNeeded = integerLog2Ceil++tyVarBndrName :: TyVarBndr -> Name+tyVarBndrName (PlainTV n) = n+tyVarBndrName (KindedTV n _k) = n++-- | Replace Vars types given in mapping+resolve :: NameMap -> Type -> Type+resolve nmap (VarT n) = nmap Map.! n+resolve nmap (AppT t1 t2) = AppT (resolve nmap t1) (resolve nmap t2)+resolve _nmap t@(ConT _) = t+resolve _nmap t@(LitT _) = t+resolve _nmap t@(TupleT _) = t+resolve _nmap t = error $ "Unexpected type: " ++ show t++resolveCon :: NameMap -> Con -> Con+resolveCon nmap (NormalC t (unzip -> (bangs, fTypes))) =+  NormalC t $ zip bangs $ map (resolve nmap) fTypes+resolveCon _name constr =+  error $ "Unexpected constructor: " ++ show constr++collectTypeArgs :: Type -> (Type, [Type])+collectTypeArgs t@(ConT _name) = (t, [])+collectTypeArgs (AppT t1 t2) =+  let (base, args) = collectTypeArgs t1 in+  (base, args ++ [t2])+collectTypeArgs t =+  error $ "Unexpected type: " ++ show t++-- | Returns size in number of bits of given type. Relies on the presence of a+-- BitSize implementation. Tries to recognize literal values and return a simple+-- expression.+typeSize :: Type -> Q Exp+typeSize typ = do+  bitSizeInstances <- reifyInstances ''BitSize [typ]+  case bitSizeInstances of+    [] ->+      error $ unwords [+          "Could not find custom bit representation nor BitSize instance"+        , "for", show typ ++ "." ]+#if MIN_VERSION_template_haskell(2,15,0)+    [TySynInstD (TySynEqn _ _ (LitT (NumTyLit n)))] ->+#else+    [TySynInstD _ (TySynEqn _ (LitT (NumTyLit n)))] ->+#endif+      [| n |]+    [_impl] ->+      [| fromIntegral $ natVal (Proxy :: Proxy (BitSize $(return typ))) |]+    unexp ->+      error $ "Unexpected result from reifyInstances: " ++ show unexp++-- | Generate bitmask from a given bit, with a certain size+bitmask+  :: Int+  -- ^ Bitmask starts at bit /n/+  -> Int+  -- ^ Bitmask has size /m/+  -> Integer+bitmask _start 0    = 0+bitmask start  size+  | start < 0        = error $ "Start cannot be <0. Was: " ++ show start+  | size < 0         = error $ "Size cannot be <0. Was: " ++ show size+  | start + 1 < size = error $ "Start + 1 (" ++ show start ++ " - 1) cannot be smaller than size (" ++ show size ++  ")."+  | otherwise        = shiftL (2^(toInteger size) - 1) (start - (size - 1))+++fieldTypes :: Con -> [Type]+fieldTypes (NormalC _nm bTys) =+  [ty | (_, ty) <- bTys]+fieldTypes (RecC _nm bTys) =+  [ty | (_, _, ty) <- bTys]+fieldTypes (InfixC (_, ty1) _nm (_, ty2)) =+  [ty1, ty2]+fieldTypes con =+  error $ "Unexpected constructor type: " ++ show con++conName :: Con -> Name+conName c = case c of+  NormalC nm _  -> nm+  RecC    nm _  -> nm+  InfixC _ nm _ -> nm+  _ -> error $ "No GADT support"++constrFieldSizes+  :: Con+  -> (Name, [Q Exp])+constrFieldSizes con = do+  (conName con, map typeSize $ fieldTypes con)++complementInteger :: Int -> Integer -> Integer+complementInteger 0 _i = 0+complementInteger size i =+  let size' = size - 1 in+  if testBit i size' then+    complementInteger size' i+  else+    (.|.) (bit size') (complementInteger size' i)++deriveAnnotation :: Derivator -> Q Type -> Q [Dec]+deriveAnnotation deriv typ =+  return <$> pragAnnD ModuleAnnotation (deriv =<< typ)++--------------------------------------------+------------ SIMPLE DERIVATIONS ------------+--------------------------------------------+buildConstrRepr+  :: Q Exp+  -- ^ Data size (excluding constructor size)+  -> Name+  -- ^ Constr name+  -> [Q Exp]+  -- ^ Field masks+  -> BitMask+  -- ^ Constructor mask+  -> Value+  -- ^ Constructor value+  -> Q Exp+buildConstrRepr dataSize constrName fieldAnns constrMask constrValue = [|+  ConstrRepr+    constrName+    $mask+    $value+    $(listE fieldAnns)+  |]+  where+    mask  = [| shiftL constrMask  ($dataSize)|]+    value = [| shiftL constrValue ($dataSize)|]++countConstructor :: [Int] -> [(BitMask, Value)]+countConstructor ns = zip (repeat mask) (map toInteger ns)+  where+    maskSize = bitsNeeded $ toInteger $ maximum ns + 1+    mask = 2^maskSize - 1++oneHotConstructor :: [Int] -> [(BitMask, Value)]+oneHotConstructor ns = zip values values+  where+    values = [shiftL 1 n | n <- ns]++overlapFieldAnnsL :: [[Q Exp]] -> [[Q Exp]]+overlapFieldAnnsL fieldSizess = map go fieldSizess+  where+    fieldSizess'  = listE $ map listE fieldSizess+    constructorSizes = [| map sum $fieldSizess' |]+    go fieldSizes =+      snd $+      mapAccumL+        (\start size -> ([| $start - $size |], [| bitmask $start $size |]))+        [| maximum $constructorSizes - 1 |]+        fieldSizes++overlapFieldAnnsR :: [[Q Exp]] -> [[Q Exp]]+overlapFieldAnnsR fieldSizess = map go fieldSizess+  where+    fieldSizess'  = listE $ map listE fieldSizess+    constructorSizes = [| map sum $fieldSizess' |]+    go fieldSizes =+      snd $+      mapAccumL+        (\start size -> ([| $start - $size |], [| bitmask $start $size |]))+        [| maximum $constructorSizes - (maximum $constructorSizes - sum $(listE fieldSizes)) - 1 |]+        fieldSizes++wideFieldAnns :: [[Q Exp]] -> [[Q Exp]]+wideFieldAnns fieldSizess = zipWith id (map go constructorOffsets) fieldSizess+  where+    constructorSizes =+      map (AppE (VarE 'sum) <$>) (map listE fieldSizess)++    constructorOffsets :: [Q Exp]+    constructorOffsets =+      init $+      scanl+        (\offset size -> [| $offset + $size |])+        [| 0 |]+        constructorSizes++    dataSize = [| sum $(listE constructorSizes) |]++    go :: Q Exp -> [Q Exp] -> [Q Exp]+    go offset fieldSizes =+      snd $+      mapAccumL+        (\start size -> ([| $start - $size |], [| bitmask $start $size |]))+        [| $dataSize - 1 - $offset |]+        fieldSizes++-- | Derive DataRepr' for a specific type.+deriveDataRepr+  :: ([Int] -> [(BitMask, Value)])+  -- ^ Constructor derivator+  -> ([[Q Exp]] -> [[Q Exp]])+  -- ^ Field derivator+  -> Derivator+deriveDataRepr constrDerivator fieldsDerivator typ = do+  info <- reify tyConstrName+  case info of+    (TyConI (DataD [] _constrName vars _kind dConstructors _clauses)) ->+      let varMap = Map.fromList $ zip (map tyVarBndrName vars) typeArgs in+      let resolvedConstructors = map (resolveCon varMap) dConstructors in do++      -- Get sizes and names of all constructors+      let+        (constrNames, fieldSizess) =+          unzip $ map constrFieldSizes resolvedConstructors++      let+        (constrMasks, constrValues) =+          unzip $ constrDerivator [0..length dConstructors - 1]++      let constrSize    = 1 + (msb $ maximum constrMasks)+      let fieldAnns     = fieldsDerivator fieldSizess+      let fieldAnnsFlat = listE $ concat fieldAnns++      let dataSize | null $ concat fieldAnns = [| 0 |]+                   | otherwise = [| 1 + (msb $ maximum $ $fieldAnnsFlat) |]++      -- Determine at which bits various fields start+      let constrReprs = zipWith4+                          (buildConstrRepr dataSize)+                          constrNames+                          fieldAnns+                          constrMasks+                          constrValues++      [| DataReprAnn+          $(liftQ $ return typ)+          ($dataSize + constrSize)+          $(listE constrReprs) |]+    _ ->+      error $ "Could not derive dataRepr for: " ++ show info++    where+      (ConT tyConstrName, typeArgs) = collectTypeArgs typ++-- | Simple derivators change the (default) way Clash stores data types. It+-- assumes no overlap between constructors and fields.+simpleDerivator :: ConstructorType -> FieldsType -> Derivator+simpleDerivator ctype ftype = deriveDataRepr constrDerivator fieldsDerivator+  where+    constrDerivator =+      case ctype of+        Binary -> countConstructor+        OneHot -> oneHotConstructor++    fieldsDerivator =+      case ftype of+        OverlapL -> overlapFieldAnnsL+        OverlapR -> overlapFieldAnnsR+        Wide -> wideFieldAnns++-- | Derives bit representation corresponding to the default manner in which+-- Clash stores types.+defaultDerivator :: Derivator+defaultDerivator = simpleDerivator Binary OverlapL++-- | Derives bit representation corresponding to the default manner in which+-- BlueSpec stores types.+blueSpecDerivator :: Derivator+blueSpecDerivator = simpleDerivator Binary OverlapR++-- | Derives bit representation corresponding to the default manner in which+-- Clash stores types.+deriveDefaultAnnotation :: Q Type -> Q [Dec]+deriveDefaultAnnotation = deriveAnnotation defaultDerivator+++-- | Derives bit representation corresponding to the default manner in which+-- BlueSpec stores types.+deriveBlueSpecAnnotation :: Q Type -> Q [Dec]+deriveBlueSpecAnnotation = deriveAnnotation blueSpecDerivator++---------------------------------------------------------------+------------ DERIVING PACKED MAYBE REPRESENTATIONS ------------+---------------------------------------------------------------+toBits'+  :: Bits a+  => Size+  -> a+  -> [Bit']+toBits' 0 _ = []+toBits' size bits = bit' : toBits' (size - 1) bits+  where bit' = if testBit bits (size - 1) then H else L++bitsToInteger' :: (Bit' -> Bool) -> [Bit'] -> Integer+bitsToInteger' predFunc bits = foldl setBit 0 toSet+  where+    toSet = [n | (n, b) <- zip [0..] (reverse bits), predFunc b]++bitsToInteger :: [Bit'] -> Integer+bitsToInteger = bitsToInteger' (==H)++bitsToMask :: [Bit'] -> Integer+bitsToMask = bitsToInteger' (\b -> b == H || b == L)++data Bit'+  = X+  -- ^ Could be both 1 or 0+  | L+  -- ^ 0+  | H+  -- ^ 1+  | U+  -- ^ Unused+    deriving (Show, Eq, Generic, NFData)++-- | Given a number of possible values, construct a list of all complement values.+-- For example, Given a list:+--+-- @+-- [[HH, HH], [LL, LL]]+-- @+--+-- then:+--+-- @+-- [[HH, LL], [LL, HH]]+-- @+--+-- would be complements.+complementValues+  :: Size+  -> [[Bit']]+  -> [[Bit']]+complementValues 0 _ = []+complementValues 1 xs+  | X `elem` xs'                 = []+  | H `elem` xs' && L `elem` xs' = []+  | H `elem` xs'                 = [[L]]+  | otherwise                    = [[H]]+  where+    xs' = map head xs+complementValues size [] = [replicate size U]+complementValues size values =+  if | all (==U) (map head values') -> map (U:) (recc (map tail values'))+     | any (==X) (map head values') -> map (X:) (recc (map tail values'))+     | otherwise ->+        (map (L:) (recc (map tail lows))) +++        (map (H:) (recc (map tail highs')))+  where+    values'       = filter (any (/= U)) values+    recc          = complementValues (size - 1)+    (highs, lows) = partition ((== H) . head) values'+    highs'        = highs ++ filter ((`elem` [X, U]) . head) values'++-- | Generate all bitvalues the given type can assume.+possibleValues+  :: ReprAnnCache+  -> Type+  -> Size+  -> Q [[Bit']]+possibleValues typeMap typ size =+  let (ConT typeName, _typeArgs) = collectTypeArgs typ in++  case Map.lookup typ typeMap of+    -- No custom data representation found.+    Nothing -> do+      info <- reify typeName+      case info of+        -- TODO: check if fields have custom bit representations+        (TyConI (DataD [] _constrName _vars _kind dConstructors _clauses)) ->+          let nConstrBits = bitsNeeded (toInteger $ length dConstructors) in+          let fieldBits = replicate (size - nConstrBits) X in+          let constrBits = [toBits' nConstrBits n | n <- [0..length dConstructors - 1]] in+          return $ zipWith (++) constrBits (repeat fieldBits)+        _ ->+          return [replicate size X]++    Just (dataReprAnnToDataRepr' -> dataRepr) ->+      -- TODO: check if fields have custom bit representations+      let (DataRepr' _name _size constrs) = dataRepr in+      forM constrs $ \constr -> do+        return $+          map+            (\case { Lit [Util.H] -> H;+                     Lit [Util.L] -> L;+                     Lit [Util.U] -> U;+                     Field _ _ _  -> X;+                     c -> error $ "possibleValues (2): unexpected: " ++ show c; })+            (bitOrigins' dataRepr constr)++packedMaybe :: Size -> Type -> Q (Maybe DataReprAnn)+packedMaybe size typ = do+  cache <- mkReprAnnCache <$> collectDataReprs+  values <- possibleValues cache typ size+  return $ case complementValues size values of+             (value:_) ->+               Just $ DataReprAnn+                        (AppT (ConT ''Maybe) typ)+                        size+                        [ ConstrRepr+                            'Nothing+                            (bitsToMask value)+                            (bitsToInteger value)+                            []+                        , ConstrRepr+                            'Just+                            0+                            0+                            [bitmask (size - 1) size] ]+             [] ->+               Nothing+++packedMaybeDerivator :: DataReprAnn -> Derivator+packedMaybeDerivator (DataReprAnn _ size _) typ =+  case maybeCon of+    ConT nm ->+      if nm == ''Maybe then+        let err = unwords [ "Could not derive packed maybe for:", show typ+                          , ";", "Does its subtype have any space left to store"+                          , "the constructor in?" ] in+        lift =<< (fromMaybe $ error err) <$> (packedMaybe (size - 1) maybeTyp)+      else+        error $ unwords [ "You can only pass Maybe types to packedMaybeDerivator,"+                        , "not", show nm]+    unexpected ->+      error $ "packedMaybeDerivator: unexpected constructor: " ++ show unexpected+  where+    (maybeCon, head -> maybeTyp) = collectTypeArgs typ++-- | Derive a compactly represented version of @Maybe a@.+derivePackedMaybeAnnotation :: DataReprAnn -> Q [Dec]+derivePackedMaybeAnnotation defaultDataRepr@(DataReprAnn typ _ _) = do+  deriveAnnotation (packedMaybeDerivator defaultDataRepr) (return typ)++---------------------------------------------------------+------------ DERIVING PACKED REPRESENTATIONS ------------+---------------------------------------------------------+packedConstrRepr+  :: Int+  -- ^ Data width+  -> Int+  -- ^ External constructor width+  -> Int+  -- ^ nth External so far+  -> [(BitMaskOrigin, ConstrRepr)]+  -> [ConstrRepr]+packedConstrRepr _ _ _ [] = []+packedConstrRepr dataWidth constrWidth n ((External, ConstrRepr name _ _ anns) : constrs) =+  constr : packedConstrRepr dataWidth constrWidth (n+1) constrs+  where+    constr =+      ConstrRepr+        name+        (shiftL (2^constrWidth - 1) dataWidth)+        (shiftL (toInteger n) dataWidth)+        anns++packedConstrRepr dataWidth constrWidth n ((Embedded mask value, ConstrRepr name _ _ anns) : constrs) =+  constr : packedConstrRepr dataWidth constrWidth n constrs+  where+    constr =+      ConstrRepr+        name+        mask+        value+        anns++packedDataRepr+  :: Type+  -> Size+  -> [(BitMaskOrigin, ConstrRepr)]+  -> DataReprAnn+packedDataRepr typ dataWidth constrs =+  DataReprAnn+    typ+    (dataWidth + constrWidth)+    (packedConstrRepr dataWidth constrWidth 0 constrs)+  where+    external    = filter isExternal (map fst constrs)+    constrWidth = bitsNeeded $ toInteger $ min (length external + 1) (length constrs)++-- | Try to distribute constructor bits over fields+storeInFields+  :: Int+  -- ^ data width+  -> BitMask+  -- ^ Additional mask gathered so far+  -> [BitMask]+  -- ^ Repr bitmasks to try and pack+  -> [BitMaskOrigin]+storeInFields _dataWidth _additionalMask [] = []+storeInFields _dataWidth _additionalMask [_] =+  -- Last constructor is implict+  [Embedded 0 0]+storeInFields dataWidth additionalMask constrs =+  if commonMask == fullMask then+    -- We can't store the constructor anywhere special, so we need a special+    -- constructor bit stored besides fields+    External : storeInFields dataWidth additionalMask (tail constrs)+  else+    -- Hooray, we can store it somewhere.+    maskOrigins ++ (storeInFields dataWidth additionalMask' (drop storeSize constrs))++  where+    headMask   = head constrs+    commonMask = (.|.) headMask additionalMask++    -- Variables for the case that we can store something:+    storeMask       = complementInteger dataWidth commonMask+    additionalMask' = (.|.) additionalMask storeMask+    storeSize       = 2^(popCount storeMask) - 1+    maskOrigins     = [Embedded storeMask (toInteger n) | n <- [1..storeSize]]++    -- BitMask which spans the complete data size+    fullMask = 2^dataWidth - 1++derivePackedAnnotation' :: DataReprAnn -> DataReprAnn+derivePackedAnnotation' (DataReprAnn typ size constrs) =+  dataRepr+  where+    constrWidth = bitsNeeded $ toInteger $ length constrs+    dataWidth   = size - constrWidth+    fieldMasks  = [foldl (.|.) zeroBits anns | ConstrRepr _ _ _ anns <- constrs]++    -- Default annotation will overlap "to the left", so sorting on size will+    -- actually provide us with the 'fullest' constructors first and the+    -- 'empties' last.+    sortedMasks = reverse $ sortOn fst $ zip fieldMasks constrs+    origins     = storeInFields dataWidth zeroBits (map fst sortedMasks)+    constrs'    = zip origins $ map snd sortedMasks+    dataRepr    = packedDataRepr typ dataWidth constrs'++-- | This derivator tries to distribute its constructor bits over space left+-- by the difference in constructor sizes. Example:+--+-- @+-- type SmallInt = Unsigned 2+--+-- data Train+--    = Passenger SmallInt+--    | Freight SmallInt SmallInt+--    | Maintenance+--    | Toy+-- @+--+-- The packed representation of this data type needs only a single constructor+-- bit. The first bit discriminates between @Freight@ and non-@Freight@+-- constructors. All other constructors do not use their last two bits; the+-- packed representation will store the rest of the constructor bits there.+packedDerivator :: Derivator+packedDerivator typ =+  [| derivePackedAnnotation' $(defaultDerivator typ ) |]++derivePackedAnnotation :: Q Type -> Q [Dec]+derivePackedAnnotation = deriveAnnotation packedDerivator++----------------------------------------------------+------------ DERIVING BITPACK INSTANCES ------------+----------------------------------------------------++-- | Collect data reprs of current module+collectDataReprs :: Q [DataReprAnn]+collectDataReprs = do+  thisMod <- thisModule+  go [thisMod] Set.empty []+  where+    go []     _visited acc = return acc+    go (x:xs) visited  acc+      | x `Set.member` visited = go xs visited acc+      | otherwise = do+          ModuleInfo newMods <- reifyModule x+          newAnns <- reifyAnnotations $ AnnLookupModule x+          go (newMods ++ xs) (x `Set.insert` visited) (newAnns ++ acc)++group :: [Bit] -> [(Int, Bit)]+group [] = []+group bs = (length head', head bs) : rest+  where+    tail' = dropWhile (==head bs) bs+    head' = takeWhile (==head bs) bs+    rest  = group tail'++bitToExpr' :: (Int, Bit) -> Q Exp -- BitVector n+bitToExpr' (0, _) = error $ "Unexpected group length: 0"+bitToExpr' (numTyLit' -> n, Util.H) =+  [| complement (resize (pack low) :: BitVector $n) |]+bitToExpr' (numTyLit' -> n, Util.L) =+  [| resize (pack low) :: BitVector $n |]+bitToExpr' (numTyLit' -> n, _) =+  [| undefined# :: BitVector $n |]++bitsToExpr :: [Bit] -> Q Exp -- BitVector n+bitsToExpr [] = error $ "Unexpected empty bit list"+bitsToExpr bits =+  foldl1+    (\v1 v2 -> [| $v1 ++# $v2 |])+    (map bitToExpr' $ group bits)++numTyLit' :: Integral a => a -> Q Type+numTyLit' n = LitT <$> (numTyLit $ toInteger n)++-- | Select a list of ranges from a bitvector expression+select'+  :: Exp+  -> [(Int, Int)]+  -> Q Exp+select' _vec [] =+  error $ "Unexpected empty list of intervals"+select' vec ranges =+  foldl1 (\v1 v2 -> [| $v1 ++# $v2 |]) $ map (return . select'') ranges+    where+      select'' :: (Int, Int) -> Exp+      select'' (from, downto) =+        let size = from - downto + 1 in+        let+          shifted+            | downto == 0 =+                vec+            | otherwise =+                AppE+                  (AppE (VarE 'shiftR) vec)+                  (LitE $ IntegerL $ toInteger downto) in++        SigE+          -- Select from whole vector+          (AppE (VarE 'resize) shifted)+          -- Type signature:+          (AppT (ConT ''BitVector) (LitT $ NumTyLit $ toInteger size))++-- | Select a range (bitorigin) from a bitvector+select+  :: [Exp]+  -- ^ BitVectors of fields+  -> BitOrigin+  -- ^ Select bits+  -> Q Exp+select _fields (Lit []) =+  error $ "Unexpected empty literal."+select _fields (Lit lits) = do+  let size = length lits+  vec <- bitsToExpr lits+  return $ SigE+            -- Apply bLit to literal string+            vec+            -- Type signature:+            (AppT (ConT ''BitVector) (LitT $ NumTyLit $ toInteger size))++select fields (Field fieldn from downto) =+  select' (fields !! fieldn) [(from, downto)]++buildPackMatch+  :: DataReprAnn+  -> ConstrRepr+  -> Q Match+buildPackMatch dataRepr cRepr@(ConstrRepr name _ _ fieldanns) = do+  fieldNames <-+    mapM (\n -> newName $ "field" ++ show n) [0..length fieldanns-1]+  fieldPackedNames <-+    mapM (\n -> newName $ "fieldPacked" ++ show n) [0..length fieldanns-1]++  let packed fName = AppE (VarE 'pack) (VarE fName)+  let pack' pName fName = ValD (VarP pName) (NormalB $ packed fName) []+  let fieldPackedDecls = zipWith pack' fieldPackedNames fieldNames+  let origins = bitOrigins+                  (dataReprAnnToDataRepr' dataRepr)+                  (constrReprToConstrRepr' undefined cRepr)++  vec <- foldl1+              (\v1 v2 -> [| $v1 ++# $v2 |])+              (map (select $ map VarE fieldPackedNames) origins)++  return $ Match (ConP name (VarP <$> fieldNames)) (NormalB vec) fieldPackedDecls++-- | Build a /pack/ function corresponding to given DataRepr+buildPack+  :: DataReprAnn+  -> Q [Dec]+buildPack dataRepr@(DataReprAnn _name _size constrs) = do+  argNameIn    <- newName "toBePackedIn"+  argName      <- newName "toBePacked"+  constrs'     <- mapM (buildPackMatch dataRepr) constrs+  let packBody    = CaseE (VarE argName) constrs'+  let packLambda  = LamE [VarP argName] packBody+  let packApplied = (VarE 'dontApplyInHDL) `AppE` (VarE 'packXWith `AppE` packLambda) `AppE` (VarE argNameIn)+  let func        = FunD 'pack [Clause [VarP argNameIn] (NormalB packApplied) []]+  return [func]+++-- | In Haskell apply the first argument to the second argument,+--   in HDL just return the second argument.+--+-- This is used in the generated pack/unpack to not do anything in HDL.+dontApplyInHDL :: (a -> b) -> a -> b+dontApplyInHDL f a = f a+{-# NOINLINE dontApplyInHDL #-}++buildUnpackField+  :: Name+  -> Integer+  -> Q Exp+buildUnpackField valueName mask =+  let ranges = bitRanges mask in+  let vec = select' (VarE valueName) ranges in+  [| unpack $vec |]++buildUnpackIfE+  :: Name+  -> ConstrRepr+  -> Q (Guard, Exp)+buildUnpackIfE valueName (ConstrRepr name mask value fieldanns) = do+  let valueName' = return $ VarE valueName+  guard  <- NormalG <$> [| ((.&.) $valueName' mask) == value |]+  fields <- mapM (buildUnpackField valueName) fieldanns+  return (guard, foldl AppE (ConE name) fields)++-- | Build an /unpack/ function corresponding to given DataRepr+buildUnpack+  :: DataReprAnn+  -> Q [Dec]+buildUnpack (DataReprAnn _name _size constrs) = do+  argNameIn   <- newName "toBeUnpackedIn"+  argName     <- newName "toBeUnpacked"+  matches     <- mapM (buildUnpackIfE argName) constrs+  let fallThroughLast []      = []+      fallThroughLast [(_,e)] = [(NormalG (ConE 'True), e)]+      fallThroughLast (x:xs)  = x:fallThroughLast xs++  let unpackBody    = MultiIfE (fallThroughLast matches)+  let unpackLambda  = LamE [VarP argName] unpackBody+  let unpackApplied = (VarE 'dontApplyInHDL) `AppE` unpackLambda `AppE` (VarE argNameIn)+  let func          = FunD 'unpack [Clause [VarP argNameIn] (NormalB unpackApplied) []]+  return [func]++-- | Derives BitPack instances for given type. Will account for custom bit+-- representation annotations in the module where the splice is ran. Note that+-- the generated instance might conflict with existing implementations (for+-- example, an instance for /Maybe a/ exists, yielding conflicts for any+-- alternative implementations).+deriveBitPack :: Q Type -> Q [Dec]+deriveBitPack typQ = do+  anns <- collectDataReprs+  typ  <- typQ++  let ann = case filter (\(DataReprAnn t _ _) -> t == typ) anns of+              [a] -> a+              []  -> error $ "No custom bit annotation found."+              _   -> error $ "Overlapping bit annotations found."++  packFunc   <- buildPack ann+  unpackFunc <- buildUnpack ann++  let (DataReprAnn _name dataSize _constrs) = ann++  let bitSizeInst = mkTySynInstD ''BitSize [typ] (LitT (NumTyLit $ toInteger dataSize))++  let bpInst = [ InstanceD+                   (Just Overlapping)+                   -- Overlap+                   []+                   -- Context+                   (AppT (ConT ''BitPack) typ)+                   -- Type+                   (bitSizeInst : packFunc ++ unpackFunc)+                   -- Declarations+               ]+  alreadyIsInstance <- isInstance ''BitPack [typ]+  if alreadyIsInstance then+    error $ show typ ++ " already has a BitPack instance."+  else+    return bpInst
+ src/Clash/Annotations/BitRepresentation/Internal.hs view
@@ -0,0 +1,118 @@+{-|+Copyright  :  (C) 2018, Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE DeriveAnyClass     #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE TemplateHaskell    #-}++module Clash.Annotations.BitRepresentation.Internal+  ( buildCustomReprs+  , dataReprAnnToDataRepr'+  , constrReprToConstrRepr'+  , getConstrRepr+  , getDataRepr+  , thTypeToType'+  , ConstrRepr'(..)+  , DataRepr'(..)+  , Type'(..)+  , CustomReprs+  ) where++import           Clash.Annotations.BitRepresentation+  (BitMask, Value, Size, FieldAnn, DataReprAnn(..), ConstrRepr(..))+import           Control.DeepSeq                          (NFData)+import           Data.Hashable                            (Hashable)+import qualified Data.Map                                 as Map+import qualified Data.Text                                as Text+import           Data.Typeable                            (Typeable)+import qualified Language.Haskell.TH.Syntax               as TH+import           GHC.Generics                             (Generic)+++-- | Simple version of template haskell type. Used internally to match on.+data Type'+  = AppTy' Type' Type'+  -- ^ Type application+  | ConstTy' Text.Text+  -- ^ Qualified name of type+  | LitTy' Integer+  -- ^ Numeral literal (used in BitVector 10, for example)+    deriving (Generic, NFData, Eq, Typeable, Hashable, Ord, Show)++-- | Internal version of DataRepr+data DataRepr' =+  DataRepr'+    -- Qualified name of type (recursive):+    Type'+    -- Size of data type:+    Size+    -- Constructors:+    [ConstrRepr']+      deriving (Show, Generic, NFData, Eq, Typeable, Hashable, Ord)++-- | Internal version of ConstrRepr+data ConstrRepr' =+  ConstrRepr'+    -- Qualified name of constructor:+    Text.Text+    -- Syntactical position in the custom representations definition:+    Int+    -- Mask needed to determine constructor:+    BitMask+    -- Value after applying mask:+    Value+    -- Indicates where fields are stored:+    [FieldAnn]+      deriving (Show, Generic, NFData, Eq, Typeable, Ord, Hashable)++constrReprToConstrRepr' :: Int -> ConstrRepr -> ConstrRepr'+constrReprToConstrRepr' n (ConstrRepr name mask value fieldanns) =+  ConstrRepr' (thToText name) n mask value (map fromIntegral fieldanns)++dataReprAnnToDataRepr' :: DataReprAnn -> DataRepr'+dataReprAnnToDataRepr' (DataReprAnn typ size constrs) =+  DataRepr' (thTypeToType' typ) size (zipWith constrReprToConstrRepr' [0..] constrs)++thToText :: TH.Name -> Text.Text+thToText (TH.Name (TH.OccName name') (TH.NameG _namespace _pkgName (TH.ModName modName))) =+  Text.pack $ modName ++ "." ++ name'+thToText name' = error $ "Unexpected pattern: " ++ show name'++-- | Convert template haskell type to simple representation of type+thTypeToType' :: TH.Type -> Type'+thTypeToType' ty = go ty+  where+    go (TH.ConT name')   = ConstTy' (thToText name')+    go (TH.AppT ty1 ty2) = AppTy' (go ty1) (go ty2)+    go (TH.LitT (TH.NumTyLit n)) = LitTy' n+    go _ = error $ "Unsupported type: " ++ show ty++-- | Convenience type for index built by buildCustomReprs+type CustomReprs =+  ( Map.Map Type' DataRepr'+  , Map.Map Text.Text ConstrRepr'+  )++-- | Lookup data type representation based on name+getDataRepr :: Type' -> CustomReprs -> Maybe DataRepr'+getDataRepr name (reprs, _) = Map.lookup name reprs++-- | Lookup constructor representation based on name+getConstrRepr :: Text.Text -> CustomReprs -> Maybe ConstrRepr'+getConstrRepr name (_, reprs) = Map.lookup name reprs++-- | Add CustomRepr to existing index+buildCustomRepr :: CustomReprs -> DataRepr' -> CustomReprs+buildCustomRepr (dMap, cMap) d@(DataRepr' name _size constrReprs) =+  let insertConstr c@(ConstrRepr' name' _ _ _ _) cMap' = Map.insert name' c cMap' in+  (Map.insert name d dMap, foldr insertConstr cMap constrReprs)++-- | Create indices based on names of constructors and data types+buildCustomReprs :: [DataRepr'] -> CustomReprs+buildCustomReprs = foldl buildCustomRepr (Map.empty, Map.empty)
+ src/Clash/Annotations/BitRepresentation/Util.hs view
@@ -0,0 +1,156 @@+{-|+Copyright  :  (C) 2018, Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE TemplateHaskell #-}++module Clash.Annotations.BitRepresentation.Util+  ( bitOrigins+  , bitOrigins'+  , bitRanges+  , isContinuousMask+  , BitOrigin(..)+  , Bit(..)+  ) where+++import Clash.Annotations.BitRepresentation.Internal+  (DataRepr'(..), ConstrRepr'(..))+import Data.Bits  (Bits, testBit, testBit, shiftR, (.|.))+import Data.List  (findIndex, group, mapAccumL)+import Data.Tuple (swap)++data Bit+  -- | High+  = H+  -- | Low+  | L+  -- | Undefined+  | U+    deriving (Show,Eq)++-- | Result of various utilty functions. Indicates the origin of a certain bit:+-- either a literal from the constructor (or an undefined bit), or from a+-- literal.+data BitOrigin+  -- | Literal (high, low, undefind)+  = Lit [Bit]+  -- | Bits originate from a field. Field /fieldnr/ /from/ /downto/.+  | Field+      Int+      -- Field number+      Int+      -- Start bit (from..)+      Int+      -- End bit (inclusive, ..downto)+        deriving (Show)++-- | Same as bitOrigins, but each item in result list represents a single bit.+bitOrigins'+  :: DataRepr'+  -> ConstrRepr'+  -> [BitOrigin]+bitOrigins' (DataRepr' _ size constrs) (ConstrRepr' _ _ mask value fields) =+  map bitOrigin (reverse [0..fromIntegral $ size - 1])+    where+      commonMask = foldl (.|.) 0 [m | ConstrRepr' _ _ m _ _ <- constrs]++      -- | Determine origin of single bit+      bitOrigin :: Int -> BitOrigin+      bitOrigin n =+        if testBit mask n then+          Lit [if testBit value n then H else L]+        else+          case findIndex (\fmask -> testBit fmask n) fields of+            Nothing ->+              if testBit commonMask n then+                -- This bit is not used in this constructor, nor is it part of+                -- a field. We cannot leave this value uninitialized though, as+                -- this would result in undefined behavior when matching other+                -- constructors. We therefore take a /default/ bit value.+                Lit [if testBit value n then H else L]+              else+                -- This bit is not used in this constructor, nor is it part of+                -- a field, nor is it used in other constructors. It is safe to+                -- leave this bit uninitialized.+                Lit [U]+            Just fieldn ->+              let fieldbitn = length $ filter id+                                     $ take n+                                     $ bitsToBools (fields !! fieldn) in+              Field fieldn fieldbitn fieldbitn++-- | Given a type size and one of its constructor this function will yield a+-- specification of which bits the whole type is made up of. I.e., a+-- construction plan on how to make the whole data structure, given its+-- individual constructor fields.+bitOrigins+  :: DataRepr'+  -> ConstrRepr'+  -> [BitOrigin]+bitOrigins dataRepr constrRepr =+  mergeOrigins (bitOrigins' dataRepr constrRepr)++-- | Merge consequtive Constructor and Field fields (if applicable).+mergeOrigins :: [BitOrigin] -> [BitOrigin]+mergeOrigins (Lit n : Lit n' : fs) =+  -- Literals can always be merged:+  mergeOrigins $ Lit (n ++ n') : fs+mergeOrigins (Field n s e : Field n' s' e' : fs)+  -- Consequtive fields with same field number merged:+  | n == n'   = mergeOrigins $ Field n s e' : fs+  -- No merge:+  | otherwise = Field n s e : mergeOrigins (Field n' s' e' : fs)+-- Base cases:+mergeOrigins (x:fs) = x : mergeOrigins fs+mergeOrigins []     = []++-- | Convert a number to a list of its bits+-- Output is ordered from least to most significant bit.+-- Only outputs bits until the highest set bit.+--+-- >>> map bitsToBools [0..2]+-- [[],[True],[False,True]])+--+-- This also works for variable sized number like Integer.+-- But not for negative numbers, because negative Integers have infinite bits set.+bitsToBools :: (Num a, Bits a, Ord a) => a -> [Bool]+bitsToBools 0 = []+bitsToBools n | n < 0 = error "Can't deal with negative bitmasks/values"+              | otherwise = testBit n 0 : bitsToBools (n `shiftR` 1)+++offsets+  :: Int+  -- ^ Offset+  -> [Bool]+  -- ^ Group+  -> (Int, (Int, [Bool]))+offsets offset group' =+  (length group' + offset, (offset, group'))++-- | Determine consecutively set bits in word. Will produce ranges from high+-- to low. Examples:+--+--   bitRanges 0b10          == [(1,1)]+--   bitRanges 0b101         == [(2,2),(0,0)]+--   bitRanges 0b10011001111 == [(10,10),(7,6),(3,0)]+--+bitRanges :: Integer -> [(Int, Int)]+bitRanges word = reverse $ map swap ranges+  where+    ranges  = map (\(ofs, grp) -> (ofs, ofs+length grp-1)) groups'+    groups' = filter (head . snd) groups+    groups  = snd $ mapAccumL offsets 0 (group bits)+    bits    = bitsToBools word++isContinuousMask :: Integer -> Bool+isContinuousMask word =+  -- Use case expression so we avoid calculating all groups+  case bitRanges word of+    -- At least two groups:+    (_:_:_) -> False+    -- Zero or one group:+    _       -> True
src/Clash/Annotations/Primitive.hs view
@@ -1,5 +1,5 @@ {-|-Copyright  :  (C) 2017, Myrtle Software, QBayLogic+Copyright  :  (C) 2017-2019, Myrtle Software, QBayLogic License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -8,21 +8,153 @@ templates. -} -{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveAnyClass        #-}+{-# LANGUAGE DeriveDataTypeable    #-}+{-# LANGUAGE DeriveFunctor         #-}+{-# LANGUAGE DeriveTraversable     #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE LambdaCase            #-}+{-# LANGUAGE TemplateHaskellQuotes #-}  {-# LANGUAGE Safe #-}  {-# OPTIONS_HADDOCK show-extensions #-} -module Clash.Annotations.Primitive where+module Clash.Annotations.Primitive+  ( dontTranslate+  , hasBlackBox+  , warnNonSynthesizable+  , warnAlways+  , Primitive(..)+  , PrimitiveGuard(..)+  , HDL(..)+  , extractPrim+  ) where -import Data.Data+import           Control.DeepSeq                          (NFData)+import           Data.Binary                              (Binary)+import           Data.Data+import           Data.Hashable                            (Hashable)+import           GHC.Generics                             (Generic) ++-- The commented code directly below this comment is affected by an old+-- GHC bug: https://ghc.haskell.org/trac/ghc/ticket/5463. In short, NOINLINE+-- pragmas generated by Template Haskell, get ignored. We'd still like a better+-- API than manually having to write all the guard/inline pragmas some day,+-- so I'm leaving the code in for now.++{-++guard :: TH.Exp -> TH.Name -> TH.Q [TH.Dec]+guard guardExpr fName =+  pure+    [ TH.PragmaD (TH.InlineP fName TH.NoInline TH.FunLike TH.AllPhases)+    , TH.PragmaD (TH.AnnP (TH.ValueAnnotation fName) (TH.SigE guardExpr typ))+    ]+  where+    typ = TH.AppT (TH.ConT ''PrimitiveGuard) (TH.TupleT 0)++applyUnit :: TH.Exp -> TH.Exp+applyUnit e = TH.AppE e (TH.TupE [])++-- | Mark a function as having a primitive. Clash will yield an error if it+-- needs to translate this function, but no blackbox was loaded. Usage:+--+-- @+-- $(hasBlackBox 'f)+-- @+--+-- If you don't want to use TemplateHaskell, add these annotations:+--+-- @+-- {-# NOINLINE f #-}+-- {-# ANN f (HasBlackBox ()) #-}+-- @+--+hasBlackBox :: TH.Name -> TH.Q [TH.Dec]+hasBlackBox = guard (applyUnit (TH.ConE 'HasBlackBox))++-- | Mark a function as non translatable. Clash will yield an error if+-- it needs to translate this function. Usage:+--+-- @+-- $(dontTranslate 'f)+-- @+--+-- If you don't want to use TemplateHaskell, add these annotations:+--+-- @+-- {-# NOINLINE f #-}+-- {-# ANN f DontTranslate #-}+-- @+--+dontTranslate :: TH.Name -> TH.Q [TH.Dec]+dontTranslate = guard (TH.ConE 'DontTranslate)++-- | Mark a function as non synthesizable. Clash will emit the given warning+-- if instantiated outside of a testbench context. Usage:+--+-- @+-- $(warnNonSynthesizable 'f "Tread carefully, user!")+-- @+--+-- If you don't want to use TemplateHaskell, add these annotations:+--+-- @+-- {-# NOINLINE f #-}+-- {-# ANN f (WarnNonSynthesizable "Tread carefully, user!" ()) #-}+-- @+--+warnNotSynthesizable :: TH.Name -> String -> TH.Q [TH.Dec]+warnNotSynthesizable nm warning =+  guard+    (applyUnit+      (TH.AppE+        (TH.ConE 'WarnNonSynthesizable)+        (TH.LitE (TH.StringL warning))))+    nm++-- | Emit warning when translating this value.+--+-- @+-- $(warnAlways 'f "Tread carefully, user!")+-- @+--+-- If you don't want to use TemplateHaskell, add these annotations:+--+-- @+-- {-# NOINLINE f #-}+-- {-# ANN f (WarnAlways "Tread carefully, user!" ()) #-}+-- @+--+warnAlways :: TH.Name -> String -> TH.Q [TH.Dec]+warnAlways nm warning =+  guard+    (applyUnit+      (TH.AppE+        (TH.ConE 'WarnAlways)+        (TH.LitE (TH.StringL warning))))+    nm+-}++dontTranslate :: PrimitiveGuard ()+dontTranslate = DontTranslate++hasBlackBox :: PrimitiveGuard ()+hasBlackBox = HasBlackBox ()++warnNonSynthesizable :: String -> PrimitiveGuard ()+warnNonSynthesizable s = WarnNonSynthesizable s ()++warnAlways :: String -> PrimitiveGuard ()+warnAlways s = WarnAlways s ()+ data HDL   = SystemVerilog   | Verilog   | VHDL-  deriving (Eq, Show, Read, Data)+  deriving (Eq, Show, Read, Data, Generic, NFData, Hashable)  -- | The 'Primitive' constructor instructs the clash compiler to look for primitive -- HDL templates in the indicated directory. 'InlinePrimitive' is equivalent but@@ -79,9 +211,6 @@ -- nicer multiline strings. -- -- @--- {\-\# LANGUAGE DataKinds   \#-\}--- {\-\# LANGUAGE QuasiQuotes \#-\}--- -- module InlinePrimitive where -- -- import           Clash.Annotations.Primitive@@ -92,7 +221,8 @@ -- {\-\# ANN example (InlinePrimitive VHDL $ unindent [i| --   [ { \"BlackBox\" : --       { "name" : "InlinePrimitive.example"---       , "templateD" :+--       , "kind": "Declaration"+--       , "template" : --   "-- begin InlinePrimitive example: --   ~GENSYM[example][0] : block --   ~RESULT <= 1 + ~ARG[0];@@ -111,4 +241,54 @@   -- ^ Description of a primitive for a given 'HDL' in a file at 'FilePath'   | InlinePrimitive HDL String   -- ^ Description of a primitive for a given 'HDL' as an inline 'String'-  deriving (Show, Read, Data)+  deriving (Show, Read, Data, Generic, NFData, Hashable)++-- | Guard primitive functions. This will help Clash generate better error+-- messages. You can annotate a function like:++-- @+-- {-# ANN f dontTranslate #-}+-- @+--+-- or+--+-- @+-- {-# ANN f hasBlackBox #-}+-- @+--+-- or+--+-- @+-- {-# ANN f (warnNonSynthesizable "Tread carefully, user!") #-}+-- @+--+-- or+--+-- @+-- {-# ANN f (warnAlways "Tread carefully, user!") #-}+-- @+data PrimitiveGuard a+  = DontTranslate+  -- ^ Marks value as not translatable. Clash will error if it finds a blackbox+  -- definition for it, or when it is forced to translate it.+  | HasBlackBox a+  -- ^ Marks a value as having a blackbox. Clash will err if it hasn't found+  -- a blackbox+  | WarnNonSynthesizable String a+  -- ^ Marks value as non-synthesizable. This will trigger a warning if+  -- instantiated in a non-testbench context. Implies @HasBlackBox@.+  | WarnAlways String a+  -- ^ Always emit warning upon instantiation. Implies @HasBlackBox@.+    deriving (Show, Read, Data, Generic, NFData, Hashable, Functor, Foldable, Traversable, Binary)++-- | Extract primitive definition from a PrimitiveGuard. Will yield Nothing+-- for guards of value 'DontTranslate'.+extractPrim+  :: PrimitiveGuard a+  -> Maybe a+extractPrim =+  \case+    HasBlackBox a            -> Just a+    WarnNonSynthesizable _ a -> Just a+    WarnAlways _ a           -> Just a+    DontTranslate            -> Nothing
+ src/Clash/Annotations/SynthesisAttributes.hs view
@@ -0,0 +1,86 @@+{-|+  Copyright   :  (C) 2018, Google Inc.+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>++  API for synthesis attributes (sometimes refered to as "synthesis directives",+  "pragmas", or "logic synthesis directives"). This is an experimental feature,+  please report any unexpected or broken behavior to Clash's GitHub page+  (<https://github.com/clash-lang/clash-compiler/issues>).+-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE PolyKinds     #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE Safe #-}++module Clash.Annotations.SynthesisAttributes+  ( Attr(..)+  , Annotate+  ) where++import GHC.TypeLits (Symbol)+import Data.Kind (Type)++type Annotate (a :: Type) (attrs :: k) = a++-- | Synthesis attributes are directives passed to sythesis tools, such as+-- Quartus. An example of such an attribute in VHDL:+--+-- @+--   attribute chip_pin : string;+--   attribute chip_pin of sel : signal is \"C4\";+--   attribute chip_pin of data : signal is "D1, D2, D3, D4";+-- @+--+-- This would instruct the synthesis tool to map the wire /sel/ to pin /C4/, and+-- wire /data/ to pins /D1/, /D2/, /D3/, and /D4/. To achieve this in Clash, /Attr/s+-- are used. An example of the same annotation:+--+-- @+-- import Clash.Annotations.SynthesisAttributes (Attr (..), Annotate )+--+-- myFunc+--     :: (Signal System Bool \`Annotate\` 'StringAttr "chip_pin" \"C4\")+--     -> (Signal System Int4 \`Annotate\` 'StringAttr "chip_pin" "D1, D2, D3, D4")+--     -> ...+-- myFunc sel data = ...+-- {-# NOINLINE myFunc #-}+-- @+--+-- To ensure this function will be rendered as its own module, do not forget a+-- NOINLINE pragma.+--+-- Multiple attributes for the /same/ argument can be specified by using a list.+-- For example:+--+-- @+-- Signal System Bool \`Annotate\`+--   [ 'StringAttr "chip_pin" \"C4\"+--   , 'BoolAttr "direct_enable" 'True+--   , 'IntegerAttr "max_depth" 512+--   , 'Attr "keep"+--   ]+-- @+--+-- For Verilog see:+--     <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir.htm>+--+-- For VHDL, see:+--     <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vhdl/vhdl_file_dir.htm>+--+-- Warning: This is an experimental feature, please report any unexpected or broken+-- behavior to Clash's GitHub page (<https://github.com/clash-lang/clash-compiler/issues>).+data Attr+  = BoolAttr Symbol Bool+  -- ^ Attribute which argument is rendered as a bool. Example:+  -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_direct_enable.htm>+  | IntegerAttr Symbol Integer+  -- ^ Attribute which argument is rendered as a integer. Example:+  -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_max_depth.htm>+  | StringAttr Symbol Symbol+  -- ^ Attribute which argument is rendered as a string. Example:+  -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_chip.htm>+  | Attr Symbol+  -- ^ Attribute rendered as constant. Example:+  -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_keep.htm>
src/Clash/Annotations/TopEntity.hs view
@@ -5,7 +5,7 @@ Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  'TopEntity' annotations allow us to control hierarchy and naming aspects of the-CλaSH compiler. We have the 'Synthesize' and 'TestBench' annotation.+Clash compiler. We have the 'Synthesize' and 'TestBench' annotation.  === 'Synthesize' annotation @@ -18,7 +18,7 @@       (sub)entities that have not changed since the last run. Caching is based       on a @.manifest@ which is generated alongside the HDL; deleting this file       means deleting the cache; changing this file will result in /undefined/-      behaviour.+      behavior.  Functions with a 'Synthesize' annotation must adhere to the following restrictions:@@ -32,16 +32,16 @@  Also take the following into account when using 'Synthesize' annotations. -    * The CλaSH compiler is based on the GHC Haskell compiler, and the GHC+    * The Clash compiler is based on the GHC Haskell compiler, and the GHC       machinery does not understand 'Synthesize' annotations and it might       subsequently decide to inline those functions. You should therefor also       add a @{\-\# NOINLINE f \#-\}@ pragma to the functions which you give       a 'Synthesize' functions.-    * Functions with a 'Synthesize' annotation will not be specialised+    * Functions with a 'Synthesize' annotation will not be specialized       on constants.  Finally, the root module, the module which you pass as an argument to the-CλaSH compiler must either have:+Clash compiler must either have:      * A function with a 'Synthesize' annotation.     * A function called /topEntity/.@@ -64,14 +64,14 @@ type Dom50 = Dom \"System\" 20000  topEntity-  :: Clock Dom50 Source-  -> Reset Dom50 Asynchronous+  :: Clock Dom50+  -> Reset Dom50   -> Signal Dom50 Bit   -> Signal Dom50 (BitVector 8) topEntity clk rst key1 =     let  (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol @ "altpll50") clk rst          rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeToAsyncReset' pllStable)-    in   'Clash.Signal.exposeClockReset' leds pllOut rstSync+    in   'Clash.Signal.exposeClockResetEnable' leds pllOut rstSync   where     key1R  = 'Clash.Prelude.isRising' 1 key1     leds   = 'Clash.Prelude.mealy' blinkerT (1,False,0) key1R@@ -93,7 +93,7 @@           | otherwise = leds @ -The CλaSH compiler would normally generate the following+The Clash compiler would normally generate the following @blinker_topentity.vhdl@ file:  @@@ -139,7 +139,7 @@     }) \#-\} @ -The CλaSH compiler will generate the following @blinker.vhdl@ file instead:+The Clash compiler will generate the following @blinker.vhdl@ file instead:  @ -- Automatically generated VHDL-93@@ -199,6 +199,7 @@  {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DeriveLift         #-}  {-# LANGUAGE TemplateHaskellQuotes #-} @@ -258,8 +259,8 @@   lift (Synthesize name inputs output) =     TH.appsE       [ TH.conE 'Synthesize-      , TH.stringE name-      , TH.listE (map lift inputs)+      , lift name+      , lift inputs       , lift output       ]   lift (TestBench _) = error "Cannot lift a TestBench"@@ -354,17 +355,7 @@   -- 2. The prefix for any unnamed ports below the 'PortProduct'   --   -- You can use an empty String ,\"\" , in case you want an auto-generated name.-  deriving (Data,Show,Generic)--instance Lift PortName where-  lift (PortName name) =-    TH.appE (TH.conE 'PortName) (TH.stringE name)-  lift (PortProduct name ports) =-    TH.appsE-      [ TH.conE 'PortProduct-      , TH.stringE name-      , TH.listE $ map lift ports-      ]+  deriving (Data,Show,Generic,Lift)  -- | Default 'Synthesize' annotation which has no specified names for the input -- and output ports.
+ src/Clash/CPP.hs view
@@ -0,0 +1,19 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE CPP#-}+{-# OPTIONS_HADDOCK hide #-}++#ifndef MAX_TUPLE_SIZE+#define MAX_TUPLE_SIZE 62+#endif++module Clash.CPP+ ( maxTupleSize+ ) where++maxTupleSize :: Num a => a+maxTupleSize = MAX_TUPLE_SIZE
src/Clash/Class/BitPack.hs view
@@ -12,6 +12,7 @@ {-# LANGUAGE MagicHash            #-} {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TypeApplications     #-} {-# LANGUAGE TypeFamilies         #-} {-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-}@@ -19,7 +20,9 @@  {-# LANGUAGE Trustworthy #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-} {-# OPTIONS_HADDOCK show-extensions #-}  #include "MachDeps.h"@@ -30,24 +33,36 @@   , boolToBV   , boolToBit   , bitToBool+  , packXWith   ) where +import Control.Exception              (catch, evaluate) import Data.Binary.IEEE754            (doubleToWord, floatToWord, wordToDouble,                                        wordToFloat)++#if MIN_VERSION_base(4,12,0)+import Data.Complex                   (Complex)+import Data.Ord                       (Down)+#endif+ import Data.Int import Data.Word import Foreign.C.Types                (CUShort)-import GHC.TypeLits                   (KnownNat, Nat, type (+))+import GHC.TypeLits                   (KnownNat, Nat, type (+), type (-)) import Numeric.Half                   (Half (..)) import GHC.Generics+import GHC.TypeLits.Extra             (CLog, Max) import Prelude                        hiding (map)+import System.IO.Unsafe               (unsafeDupablePerformIO) +import Clash.Promoted.Nat             (SNat(..), snatToNum) import Clash.Class.BitPack.Internal   (deriveBitPackTuples)-import Clash.Class.Resize             (zeroExtend)-import Clash.Sized.BitVector-  (Bit, BitVector, (++#), high, low)-import Clash.Sized.Internal.BitVector (pack#, split#, unpack#, unsafeToInteger)+import Clash.Class.Resize             (zeroExtend, resize)+import Clash.Sized.BitVector          (Bit, BitVector, (++#))+import Clash.Sized.Internal.BitVector+  (pack#, split#, checkUnpackUndef, undefined#, unpack#, unsafeToInteger)+import Clash.XException  {- $setup >>> :set -XDataKinds@@ -61,24 +76,35 @@   --   -- Can be derived using `GHC.Generics`:   ---  -- > {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}-  -- >   -- > import Clash.Prelude   -- > import GHC.Generics   -- >   -- > data MyProductType = MyProductType { a :: Int, b :: Bool }   -- >   deriving (Generic, BitPack)   type BitSize a :: Nat-  type BitSize a = GBitSize (Rep a)+  type BitSize a = (CLog 2 (GConstructorCount (Rep a))) + (GFieldSize (Rep a))   -- | Convert element of type @a@ to a 'BitVector'   --   -- >>> pack (-5 :: Signed 6)   -- 11_1011   pack   :: a -> BitVector (BitSize a)   default pack-    :: (Generic a, GBitPack (Rep a), GBitSize (Rep a) ~ BitSize a)+    :: ( Generic a+       , GBitPack (Rep a)+       , KnownNat (BitSize a)+       , KnownNat constrSize+       , KnownNat fieldSize+       , constrSize ~ CLog 2 (GConstructorCount (Rep a))+       , fieldSize ~ GFieldSize (Rep a)+       , (constrSize + fieldSize) ~ BitSize a+       )     => a -> BitVector (BitSize a)-  pack = gpack . from+  pack = packXWith go+   where+    go a = resize (pack sc) ++# packedFields+     where+      (sc, packedFields) = gPackFields 0 (from a)+   -- | Convert a 'BitVector' to an element of type @a@   --   -- >>> pack (-5 :: Signed 6)@@ -90,10 +116,30 @@   -- 11_1011   unpack :: BitVector (BitSize a) -> a   default unpack-    :: (Generic a, GBitPack (Rep a), GBitSize (Rep a) ~ BitSize a)+    :: ( Generic a+       , GBitPack (Rep a)+       , KnownNat constrSize+       , KnownNat fieldSize+       , constrSize ~ CLog 2 (GConstructorCount (Rep a))+       , fieldSize ~ GFieldSize (Rep a)+       , (constrSize + fieldSize) ~ BitSize a+       )     => BitVector (BitSize a) -> a-  unpack = to . gunpack+  unpack b =+    to (gUnpack sc 0 bFields)+   where+    (checkUnpackUndef unpack . resize -> sc, bFields) = split# b +packXWith+  :: KnownNat n+  => (a -> BitVector n)+  -> a+  -> BitVector n+packXWith f x =+  unsafeDupablePerformIO (catch (f <$> evaluate x)+                                (\(XException _) -> return undefined#))+{-# NOINLINE packXWith #-}+ {-# INLINE bitCoerce #-} -- | Coerce a value from one type to another through its bit representation. --@@ -110,79 +156,77 @@  instance BitPack Bool where   type BitSize Bool = 1-  pack True  = 1-  pack False = 0--  unpack bv  = if bv == 1 then True else False+  pack   = let go b = if b then 1 else 0 in packXWith go+  unpack = checkUnpackUndef $ \bv -> if bv == 1 then True else False -instance BitPack (BitVector n) where+instance KnownNat n => BitPack (BitVector n) where   type BitSize (BitVector n) = n-  pack   v = v+  pack     = packXWith id   unpack v = v  instance BitPack Bit where   type BitSize Bit = 1-  pack   = pack#+  pack   = packXWith pack#   unpack = unpack#  instance BitPack Int where   type BitSize Int = WORD_SIZE_IN_BITS-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Int8 where   type BitSize Int8 = 8-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Int16 where   type BitSize Int16 = 16-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Int32 where   type BitSize Int32 = 32-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  #if WORD_SIZE_IN_BITS >= 64 instance BitPack Int64 where   type BitSize Int64 = 64-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral #endif  instance BitPack Word where   type BitSize Word = WORD_SIZE_IN_BITS-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Word8 where   type BitSize Word8 = 8-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Word16 where   type BitSize Word16 = 16-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Word32 where   type BitSize Word32 = 32-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  #if WORD_SIZE_IN_BITS >= 64 instance BitPack Word64 where   type BitSize Word64 = 64-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral #endif  instance BitPack Float where   type BitSize Float = 32-  pack   = packFloat#-  unpack = unpackFloat#+  pack   = packXWith packFloat#+  unpack = checkUnpackUndef unpackFloat#  packFloat# :: Float -> BitVector 32 packFloat# = fromIntegral . floatToWord@@ -194,8 +238,8 @@  instance BitPack Double where   type BitSize Double = 64-  pack   = packDouble#-  unpack = unpackDouble#+  pack   = packXWith packDouble#+  unpack = checkUnpackUndef unpackDouble#  packDouble# :: Double -> BitVector 64 packDouble# = fromIntegral . doubleToWord@@ -207,58 +251,145 @@  instance BitPack CUShort where   type BitSize CUShort = 16-  pack   = fromIntegral-  unpack = fromIntegral+  pack   = packXWith fromIntegral+  unpack = checkUnpackUndef fromIntegral  instance BitPack Half where   type BitSize Half = 16   pack (Half x) = pack x-  unpack x      = Half (unpack x)+  unpack        = checkUnpackUndef $ \x -> Half (unpack x)  instance BitPack () where   type BitSize () = 0   pack   _ = minBound   unpack _ = () -instance (KnownNat (BitSize b), BitPack a, BitPack b) =>+instance (KnownNat (BitSize a), KnownNat (BitSize b), BitPack a, BitPack b) =>     BitPack (a,b) where   type BitSize (a,b) = BitSize a + BitSize b-  pack (a,b) = pack a ++# pack b+  pack = let go (a,b) = pack a ++# pack b in packXWith go   unpack ab  = let (a,b) = split# ab in (unpack a, unpack b) -instance (BitPack a, KnownNat (BitSize a)) => BitPack (Maybe a) where-  type BitSize (Maybe a) = 1 + BitSize a-  pack Nothing  = pack# low ++# 0-  -- We cannot do `low ++# undefined`, because `BitVector`s underlying-  -- representation is `Integer`, so `low ++# undefined` would make the-  -- entire `BitVector` undefined.-  pack (Just x) = pack# high ++# pack x-  unpack x = case split# x of-    (c,rest) | unpack# c == low -> Nothing-             | otherwise        -> Just (unpack rest)- class GBitPack f where-  type GBitSize f :: Nat-  gpack :: f a -> BitVector (GBitSize f)-  gunpack :: BitVector (GBitSize f) -> f a+  -- | Size of fields. If multiple constructors exist, this is the maximum of+  -- the sum of each of the constructors fields.+  type GFieldSize f :: Nat -instance (GBitPack a) => GBitPack (M1 m d a) where-  type GBitSize (M1 m d a) = GBitSize a-  gpack (M1 m1)            = gpack m1-  gunpack b                = M1 (gunpack b)+  -- | Number of constructors this type has. Indirectly indicates how many bits+  -- are needed to represent the constructor.+  type GConstructorCount f :: Nat -instance (KnownNat (GBitSize g), GBitPack f, GBitPack g) => GBitPack (f :*: g) where-  type GBitSize (f :*: g) = GBitSize f + GBitSize g-  gpack (m :*: ms)        = gpack m ++# gpack ms-  gunpack b               = gunpack front :*: gunpack back-    where-      (front, back) = split# b+  -- | Pack fields of a type. Caller should pack and prepend the constructor bits.+  gPackFields+    :: Int+    -- ^ Current constructor+    -> f a+    -- ^ Data to pack+    -> (Int, BitVector (GFieldSize f))+    -- ^ (Constructor number, Packed fields) -instance (BitPack c) => GBitPack (K1 i c) where-  type GBitSize (K1 i c) = BitSize c-  gpack (K1 i)           = pack i-  gunpack b              = K1 (unpack b)+  -- | Unpack whole type.+  gUnpack+    :: Int+    -- ^ Construct with constructor /n/+    -> Int+    -- ^ Current constructor+    -> BitVector (GFieldSize f)+    -- ^ BitVector containing fields+    -> f a+    -- ^ Unpacked result +instance GBitPack a => GBitPack (M1 m d a) where+  type GFieldSize (M1 m d a) = GFieldSize a+  type GConstructorCount (M1 m d a) = GConstructorCount a++  gPackFields cc (M1 m1) = gPackFields cc m1+  gUnpack c cc b = M1 (gUnpack c cc b)++instance ( KnownNat (GFieldSize g)+         , KnownNat (GFieldSize f)+         , KnownNat (GConstructorCount f)+         , GBitPack f+         , GBitPack g+         ) => GBitPack (f :+: g) where+  type GFieldSize (f :+: g) = Max (GFieldSize f) (GFieldSize g)+  type GConstructorCount (f :+: g) = GConstructorCount f + GConstructorCount g++  gPackFields cc (L1 l) =+    let (sc, packed) = gPackFields cc l in+    let padding = undefined# :: BitVector (Max (GFieldSize f) (GFieldSize g) - GFieldSize f) in+    (sc, packed ++# padding)+  gPackFields cc (R1 r) =+    let cLeft = snatToNum (SNat @(GConstructorCount f)) in+    let (sc, packed) = gPackFields (cc + cLeft) r in+    let padding = undefined# :: BitVector (Max (GFieldSize f) (GFieldSize g) - GFieldSize g) in+    (sc, packed ++# padding)++  gUnpack c cc b =+    let cLeft = snatToNum (SNat @(GConstructorCount f)) in+    if c < cc + cLeft then+      L1 (gUnpack c cc f)+    else+      R1 (gUnpack c (cc + cLeft) g)++   where+    -- It's a thing of beauty, if I may say so myself!+    (f, _ :: BitVector (Max (GFieldSize f) (GFieldSize g) - GFieldSize f)) = split# b+    (g, _ :: BitVector (Max (GFieldSize f) (GFieldSize g) - GFieldSize g)) = split# b+++instance (KnownNat (GFieldSize g), KnownNat (GFieldSize f), GBitPack f, GBitPack g) => GBitPack (f :*: g) where+  type GFieldSize (f :*: g) = GFieldSize f + GFieldSize g+  type GConstructorCount (f :*: g) = 1++  gPackFields cc fg =+    (cc, packXWith go fg)+   where+    go (l0 :*: r0) =+      let (_, l1) = gPackFields cc l0 in+      let (_, r1) = gPackFields cc r0 in+      l1 ++# r1++  gUnpack c cc b =+    gUnpack c cc front :*: gUnpack c cc back+   where+    (front, back) = split# b++instance BitPack c => GBitPack (K1 i c) where+  type GFieldSize (K1 i c) = BitSize c+  type GConstructorCount (K1 i c)  = 1++  gPackFields cc (K1 i) = (cc, pack i)+  gUnpack _c _cc b      = K1 (unpack b)++instance GBitPack U1 where+  type GFieldSize U1 = 0+  type GConstructorCount U1 = 1++  gPackFields cc U1 = (cc, 0)+  gUnpack _c _cc _b = U1++-- Instances derived using Generic+instance ( BitPack a+         , KnownNat (BitSize a)+         , BitPack b+         , KnownNat (BitSize b)+         ) => BitPack (Either a b)++instance ( BitPack a+         , KnownNat (BitSize a)+         ) => BitPack (Maybe a)++#if MIN_VERSION_base(4,12,0)+instance ( BitPack a+         , KnownNat (BitSize a)+         ) => BitPack (Complex a)++instance ( BitPack a+         , KnownNat (BitSize a)+         ) => BitPack (Down a)+#endif+ -- | Zero-extend a 'Bool'ean value to a 'BitVector' of the appropriate size. -- -- >>> boolToBV True :: BitVector 6@@ -277,4 +408,4 @@ bitToBool = bitCoerce  -- Derive the BitPack instance for tuples of size 3 to 62-deriveBitPackTuples ''BitPack ''BitSize 'pack 'unpack '(++#)+deriveBitPackTuples ''BitPack ''BitSize 'pack 'unpack
src/Clash/Class/BitPack/Internal.hs view
@@ -1,7 +1,15 @@+{-|+Copyright  :  (C) 2019, QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}+{-# LANGUAGE CPP             #-} {-# LANGUAGE TemplateHaskell #-} -module Clash.Class.BitPack.Internal where+module Clash.Class.BitPack.Internal (deriveBitPackTuples) where +import           Clash.CPP             (maxTupleSize)+import           Language.Haskell.TH.Compat (mkTySynInstD) import           Control.Monad         (replicateM) import           Data.List             (foldl') import           GHC.TypeLits          (KnownNat)@@ -17,20 +25,20 @@   -- ^ pack   -> Name   -- ^ unpack-  -> Name-  -- ^ append (++#)   -> DecsQ-deriveBitPackTuples bitPackName bitSizeName packName unpackName appendName = do+deriveBitPackTuples bitPackName bitSizeName packName unpackName = do   let bitPack  = ConT bitPackName       bitSize  = ConT bitSizeName       knownNat = ConT ''KnownNat       plus     = ConT $ mkName "+" -  allNames <- replicateM 62 (newName "a")+  allNames <- replicateM maxTupleSize (newName "a")+  retupName <- newName "retup"   x <- newName "x"   y <- newName "y"+  tup <- newName "tup" -  pure $ flip map [3..62] $ \tupleNum ->+  pure $ flip map [3..maxTupleSize] $ \tupleNum ->     let names  = take tupleNum allNames         (v:vs) = fmap VarT names         tuple xs = foldl' AppT (TupleT $ length xs) xs@@ -45,24 +53,27 @@         instTy = AppT bitPack $ tuple (v:vs)          -- Associated type BitSize-        bitSizeTypeEq =-          TySynEqn-            [ tuple (v:vs) ]+        bitSizeType =+          mkTySynInstD bitSizeName [tuple (v:vs)]             $ plus `AppT` (bitSize `AppT` v) `AppT`               (bitSize `AppT` foldl AppT (TupleT $ tupleNum - 1) vs)-        bitSizeType = TySynInstD bitSizeName bitSizeTypeEq          pack =           FunD             packName             [ Clause-                [ TupP $ map VarP names ]-                ( let (e:es) = map VarE names-                  in NormalB $ AppE-                    (VarE appendName `AppE` (VarE packName `AppE` e))-                    (VarE packName `AppE` TupE es)-                )-                []+                [VarP tup]+                (NormalB (AppE (VarE packName) (AppE (VarE retupName) (VarE tup))))+                [FunD+                    retupName+                    [ Clause+                        [ TupP $ map VarP names ]+                        ( let (e:es) = map VarE names+                          in NormalB (TupE [e,TupE es])+                        )+                        []+                    ]+                ]             ]          unpack =
+ src/Clash/Class/Exp.hs view
@@ -0,0 +1,92 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE CPP           #-}+{-# LANGUAGE DataKinds     #-}+{-# LANGUAGE MagicHash     #-}+{-# LANGUAGE TypeFamilies  #-}+{-# LANGUAGE TypeOperators #-}++#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType  #-}+#endif++{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}++module Clash.Class.Exp (Exp, ExpResult, (^)) where++import qualified Prelude                       as P+import           Prelude                       hiding ((^))++import           Clash.Annotations.Primitive   (hasBlackBox)+import           Clash.Promoted.Nat            (SNat(..), snatToInteger)+import           Clash.Sized.Internal.Index    (Index)+import           Clash.Sized.Internal.Signed   (Signed)+import           Clash.Sized.Internal.Unsigned (Unsigned)++import           GHC.TypeLits+  (KnownNat, Nat, type (^), type (*))++-- | Type class implementing exponentiation with explicitly resizing results.+class Exp a where+  type ExpResult a (n :: Nat)++  -- | Exponentiation with known exponent.+  (^)+    :: a+    -- ^ Base+    -> SNat n+    -- ^ Exponent+    -> ExpResult a n+    -- ^ Resized result, guaranteed to not have overflown++instance KnownNat m => Exp (Index m) where+  type ExpResult (Index m) n = Index (m ^ n)++  (^) = expIndex#+  {-# INLINE (^) #-}++instance KnownNat m => Exp (Signed m) where+  type ExpResult (Signed m) n = Signed (m * n)++  (^) = expSigned#+  {-# INLINE (^) #-}++instance KnownNat m => Exp (Unsigned m) where+  type ExpResult (Unsigned m) n = Unsigned (m * n)++  (^) = expUnsigned#+  {-# INLINE (^) #-}++expIndex#+  :: KnownNat m+  => Index m+  -> SNat n+  -> Index (m ^ n)+expIndex# b e@SNat =+  fromInteger (toInteger b P.^ snatToInteger e)+{-# NOINLINE expIndex# #-}+{-# ANN expIndex# hasBlackBox #-}++expSigned#+  :: KnownNat m+  => Signed m+  -> SNat n+  -> Signed (m * n)+expSigned# b e@SNat =+  fromInteger (toInteger b P.^ snatToInteger e)+{-# NOINLINE expSigned# #-}+{-# ANN expSigned# hasBlackBox #-}++expUnsigned#+  :: KnownNat m+  => Unsigned m+  -> SNat n+  -> Unsigned (m * n)+expUnsigned# b e@SNat =+  fromInteger (toInteger b P.^ snatToInteger e)+{-# NOINLINE expUnsigned# #-}+{-# ANN expUnsigned# hasBlackBox #-}
+ src/Clash/Class/HasDomain.hs view
@@ -0,0 +1,8 @@+module Clash.Class.HasDomain+  ( WithSpecificDomain+  , WithSingleDomain+  ) where++-- Compilation is split across modules to maximize GHC parallelism+import Clash.Class.HasDomain.HasSingleDomain+import Clash.Class.HasDomain.HasSpecificDomain
+ src/Clash/Class/HasDomain/CodeGen.hs view
@@ -0,0 +1,69 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE ViewPatterns #-}++module Clash.Class.HasDomain.CodeGen+  ( mkTryDomainTuples+  , mkHasDomainTuples+  ) where++import           Language.Haskell.TH.Syntax+import           Clash.CPP                    (maxTupleSize)+import           Language.Haskell.TH.Compat   (mkTySynInstD)+++mkTup :: [Type] -> Type+mkTup names@(length -> n) =+  foldl AppT (TupleT n) names++-- | Creates an instance of the form:+--+--  type instance TryDomain t (a, b, c, d, e) = Merge t a (b, c, d, e)+--+-- With /n/ number of variables on the LHS.+mkTryDomainTupleInstance :: Name -> Name -> Int -> Dec+mkTryDomainTupleInstance tryDomainName mergeName n =+  mkTySynInstD tryDomainName [t, tupPat] tupBody+ where+  bcde = map (VarT . mkName . ("a"++) . show) [1..n-1]+  a    = VarT (mkName "a0")+  t    = VarT (mkName "t")++  -- Merge t a (b, c, d, e)+  tupBody = ConT mergeName `AppT` t `AppT` a `AppT` (mkTup bcde)++  -- (a, b, c, d, e)+  tupPat = mkTup (a : bcde)++mkTryDomainTuples :: Name -> Name -> Q [Dec]+mkTryDomainTuples tryDomainName mergeName =+  pure (map (mkTryDomainTupleInstance tryDomainName mergeName) [3..maxTupleSize])+++-- | Creates an instance of the form:+--+--  type instance HasDomain' dom (a, b, c, d, e) =+--    Merge' (HasDomain' dom a) (HasDomain' dom (b, c, d, e))+--+-- With /n/ number of variables on the LHS.+mkHasDomainTupleInstance :: Name -> Name -> Int -> Dec+mkHasDomainTupleInstance hasDomainName mergeName n =+  mkTySynInstD hasDomainName [dom, tupPat] merge+ where+  bcde = map (VarT . mkName . ("a"++) . show) [1..n-1]+  a    = VarT (mkName "a0")+  dom  = VarT (mkName "dom")++  -- Merge dom a (b, c, d, e)+  merge = ConT mergeName `AppT` dom `AppT` a `AppT` mkTup bcde++  -- (a, b, c, d, e)+  tupPat = mkTup (a : bcde)++mkHasDomainTuples :: Name -> Name -> Q [Dec]+mkHasDomainTuples hasDomainName mergeName =+  pure (map (mkHasDomainTupleInstance hasDomainName mergeName) [3..maxTupleSize])
+ src/Clash/Class/HasDomain/Common.hs view
@@ -0,0 +1,46 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE DataKinds          #-}+{-# LANGUAGE PolyKinds          #-}+{-# LANGUAGE TypeFamilies       #-}+{-# LANGUAGE TypeOperators      #-}++module Clash.Class.HasDomain.Common+  ( Unlines+  , (:<<>>:)+  , (:$$$:)+  , (:++:)+  ) where++import           GHC.TypeLits               (Symbol)+import           Type.Errors+  (ErrorMessage(Text, ShowType, (:<>:), (:$$:)))++type family ToEM (k :: t) :: ErrorMessage where+  ToEM (k :: Symbol)       = 'Text k+  ToEM (k :: ErrorMessage) = k+  ToEM (k :: t)            = 'ShowType k++infixl 5 :<<>>:+type (:<<>>:) (k1 :: t1) (k2 :: t2) = ToEM k1 ':<>: ToEM k2++infixl 4 :$$$:+type (:$$$:) (k1 :: t1) (k2 :: t2) = ToEM k1 ':$$: ToEM k2+++{- | Combine multiple lines with line break. Type-level version of the @unlines@+function but for ErrorMessage. -}+type family Unlines (ln :: [k]) :: ErrorMessage where+  Unlines '[] = 'Text ""+  Unlines ((x :: Symbol) ': xs) = 'Text x ':$$: Unlines xs+  Unlines ((x :: ErrorMessage) ': xs) = x ':$$: Unlines xs++infixl 4 :++:+type family (:++:) (as :: [k]) (bs :: [k]) :: [k] where+  (:++:) a '[] = a+  (:++:) '[] b = b+  (:++:) (a ': as) bs = a ': (as :++: bs)
+ src/Clash/Class/HasDomain/HasSingleDomain.hs view
@@ -0,0 +1,184 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE CPP                  #-}+{-# LANGUAGE ConstraintKinds      #-}+{-# LANGUAGE PolyKinds            #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE TypeOperators        #-}+{-# LANGUAGE UndecidableInstances #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# OPTIONS_GHC -Wno-missing-methods #-}++module Clash.Class.HasDomain.HasSingleDomain where++import           Clash.Class.HasDomain.Common+import           Clash.Class.HasDomain.CodeGen    (mkTryDomainTuples)++import           Clash.Sized.Vector               (Vec)+import           Clash.Sized.RTree                (RTree)+import           Clash.Signal.Internal+  (Signal, Domain, Clock, Reset, Enable)+import           Clash.Signal.Delayed.Internal    (DSignal)++import           Data.Kind                        (Type)+import           Data.Proxy                       (Proxy)+import           Type.Errors+  (DelayError, TypeError, IfStuck, Pure)++type MissingInstance =+        "This might happen if an instance for TryDomain is missing. Try to determine"+  :$$$: "which of the types miss an instance, and add them. Example implementations:"+  :$$$: ""+  :$$$: " * type instance TryDomain t (MyVector n a)    = TryDomain t a"+  :$$$: " * type instance TryDomain t (MyCircuit dom a) = Found dom"+  :$$$: " * type instance TryDomain t Terminal          = NotFound"+  :$$$: ""+  :$$$: "Alternatively, use one of the withSpecific* functions."++type Outro =+         ""+   :$$$: "------"+   :$$$: ""+   :$$$: "You tried to apply an explicitly routed clock, reset, or enable line"+   :$$$: "to a construct with, possibly, an implicitly routed one. Clash failed to"+   :$$$: "unambigously determine a single domain and could therefore not route it."+   :$$$: "You possibly used one of these sets of functions:"+   :$$$: ""+   :$$$: " * with{ClockResetEnable,Clock,Reset,Enable}"+   :$$$: " * expose{ClockResetEnable,Clock,Reset,Enable}"+   :$$$: ""+   :$$$: "These functions are suitable for components defined over a single domain"+   :$$$: "only. If you want to use multiple domains, use the following instead:"+   :$$$: ""+   :$$$: " * withSpecific{ClockResetEnable,Clock,Reset,Enable}"+   :$$$: " * exposeSpecific{ClockResetEnable,Clock,Reset,Enable}"+   :$$$: ""++type NotFoundError (t :: Type) =+       "Could not find a non-ambiguous domain in the following type:"+  :$$$: ""+  :$$$: "  " :<<>>: t+  :$$$: ""+  :$$$: MissingInstance+  :$$$: Outro++type AmbiguousError (t :: Type) (dom1 :: Domain) (dom2 :: Domain) =+        "Could not determine that the domain '" :<<>>: dom1 :<<>>: "'"+  :$$$: "was equal to the domain '" :<<>>: dom2 :<<>>: "' in the type:"+  :$$$: ""+  :$$$: "  " :<<>>: t+  :$$$: ""+  :$$$: "This is usually resolved by adding explicit type signatures."+  :$$$: Outro++type StuckErrorMsg (orig :: Type) (n :: Type) =+        "Could not determine whether the following type contained a non-ambiguous domain:"+  :$$$: ""+  :$$$: "  " :<<>>: n+  :$$$: ""+  :$$$: "In the full type:"+  :$$$: ""+  :$$$: "  " :<<>>: orig+  :$$$: ""+  :$$$: "Does it contain one?"+  :$$$: ""+  :$$$: "------"+  :$$$: ""+  :$$$: MissingInstance+  :$$$: Outro++-- | Type that forces /dom/ to be the same in all subtypes of /r/ that might+-- contain a domain. If given a polymorphic domain not tied to /r/, GHC will+-- be allowed to infer that that domain is equal to the one in /r/ on the+-- condition that /r/ contains just a single domain.+type WithSingleDomain dom r =+  (HasSingleDomain r, dom ~ GetDomain r)++data TryDomainResult+  = NotFound+  | Ambiguous Domain Domain+  | Found Domain++-- | Type family to resolve type conflicts (if any)+type family Merge' (n :: TryDomainResult) (m :: TryDomainResult) :: TryDomainResult where+  Merge' 'NotFound              b                      = b+  Merge' ('Ambiguous dom1 dom2) b                      = 'Ambiguous dom1 dom2+  Merge' a                      'NotFound              = a+  Merge' a                      ('Ambiguous dom1 dom2) = 'Ambiguous dom1 dom2+  Merge' ('Found dom)           ('Found dom)           = 'Found dom+  Merge' ('Found dom1)          ('Found dom2)          = 'Ambiguous dom1 dom2++-- | Same as Merge', but will insert a type error if Merge' got stuck.+type family Merge (orig :: Type) (n :: Type) (m :: Type) :: TryDomainResult where+  Merge orig n m =+    IfStuck+      (TryDomain orig n)+      (DelayError (StuckErrorMsg orig n))+      (Pure+        (IfStuck+          (TryDomain orig m)+          (DelayError (StuckErrorMsg orig m))+          (Pure (Merge' (TryDomain orig n) (TryDomain orig m)))+         ))++type family ErrOnConflict (t :: Type) (n :: TryDomainResult) :: Domain where+  ErrOnConflict t 'NotFound              = TypeError (NotFoundError t)+  ErrOnConflict t ('Ambiguous dom1 dom2) = TypeError (AmbiguousError t dom1 dom2)+  ErrOnConflict t ('Found dom)           = dom++type family TryDomain (orig :: Type) (n :: Type) :: TryDomainResult++type instance TryDomain t (DSignal dom delay a) = 'Found dom+type instance TryDomain t (Signal dom a)        = 'Found dom+type instance TryDomain t (Clock dom)           = 'Found dom+type instance TryDomain t (Reset dom)           = 'Found dom+type instance TryDomain t (Enable dom)          = 'Found dom+type instance TryDomain t (Proxy dom)           = 'Found dom+type instance TryDomain t (Vec n a)             = TryDomain t a+type instance TryDomain t (RTree d a)           = TryDomain t a+type instance TryDomain t (a -> b)              = Merge t a b+type instance TryDomain t (a, b)                = Merge t a b++type instance TryDomain t ()                    = 'NotFound+type instance TryDomain t Bool                  = 'NotFound+type instance TryDomain t Integer               = 'NotFound+type instance TryDomain t Int                   = 'NotFound+type instance TryDomain t Float                 = 'NotFound+type instance TryDomain t Double                = 'NotFound+type instance TryDomain t (Maybe a)             = TryDomain t a+type instance TryDomain t (Either a b)          = Merge t a b++-- TODO: Add more instances, including:+--type instance TryDomain t Bit                   = 'NotFound+--type instance TryDomain t (BitVector n)         = 'NotFound+--type instance TryDomain t (Index n)             = 'NotFound+--type instance TryDomain t (Fixed rep int frac)  = 'NotFound+--type instance TryDomain t (Signed n)            = 'NotFound+--type instance TryDomain t (Unsigned n)          = 'NotFound++-- | Type family that searches a type and checks whether all subtypes that can+-- contain a domain (for example, Signal) contain the /same/ domain. Its+-- associated type, GetDomain, will yield a type error if that doesn't hold OR+-- if it can't check it.+class HasSingleDomain (r :: Type) where+  type GetDomain r :: Domain+  type GetDomain r =+    -- Handle types not in TryDomain type family+    IfStuck+      (TryDomain r r)+      (DelayError (StuckErrorMsg r r))+      (Pure (ErrOnConflict r (TryDomain r r)))++instance HasSingleDomain a++mkTryDomainTuples ''TryDomain ''Merge
+ src/Clash/Class/HasDomain/HasSpecificDomain.hs view
@@ -0,0 +1,146 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE UndecidableInstances  #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# OPTIONS_GHC -Wno-missing-methods #-}++module Clash.Class.HasDomain.HasSpecificDomain where++import           Clash.Class.HasDomain.CodeGen  (mkHasDomainTuples)+import           Clash.Class.HasDomain.Common++import           Clash.Sized.Vector             (Vec)+import           Clash.Signal.Internal+  (Signal, Domain, Clock, Reset, Enable)+import           Clash.Signal.Delayed.Internal  (DSignal)++import           Data.Proxy                     (Proxy)+import           Data.Kind                      (Type)+import           Type.Errors+  (IfStuck, DelayError, Pure, ErrorMessage(ShowType))++type Outro =+         ""+   :$$$: "------"+   :$$$: ""+   :$$$: "You tried to apply an explicitly routed clock, reset, or enable line"+   :$$$: "to a construct with, possibly, an implicitly routed one. Clash failed to"+   :$$$: "unambigously link the given domain (by passing in a 'Clock', 'Reset', or"+   :$$$: "'Enable') to the component passed in."+   :$$$: ""++type NotFoundError (dom :: Domain) (t :: Type) =+       "Could not find domain '" :<<>>: 'ShowType dom :<<>>: "' in the following type:"+  :$$$: ""+  :$$$: "  " :<<>>: t+  :$$$: ""+  :$$$: "If that type contains that domain anyway, you might need to provide an"+  :$$$: "additional type instance of HasDomain. Example implementations:"+  :$$$: ""+  :$$$: " * type instance HasDomain dom  (MyVector n a)     = HasDomain dom a"+  :$$$: " * type instance HasDomain dom1 (MyCircuit dom2 a) = DomEq dom1 dom2"+  :$$$: " * type instance HasDomain dom1 (MyTuple a b)      = Merge dom a b"+  :$$$: ""+  :$$$: Outro++-- | Type that forces /dom/ to be present in /r/ at least once. Will resolve to+-- a type error if it doesn't. It will always fail if given /dom/ is completely+-- polymorphic and can't be tied to /r/ in any way.+type WithSpecificDomain dom r =+  (HasSpecificDomain dom r, dom ~ GetDomain dom r)++-- TODO: Extend HasDomainWrapperResult such that it keeps track of what it found /+-- TODO: which types are stuck, so that we can report better errors.+data HasDomainWrapperResult+  = NotFound+  -- ^ No domain found+  | Found+  -- ^ Found the specific domain caller was looking for++-- | Merge two 'HasDomainWrapperResult's according to the semantics of 'HasDomain.+type family MergeWorker (n :: HasDomainWrapperResult) (m :: HasDomainWrapperResult) :: HasDomainWrapperResult where+  MergeWorker 'Found b = 'Found+  MergeWorker a 'Found = 'Found+  MergeWorker 'NotFound 'NotFound = 'NotFound++type Merge (dom :: Domain) (n :: Type) (m :: Type) =+  MergeWorker (HasDomainWrapper dom n) (HasDomainWrapper dom m)++type family DomEqWorker (n :: Domain) (m :: Domain) :: HasDomainWrapperResult where+  DomEqWorker n n = 'Found+  DomEqWorker n m = 'NotFound++-- | Check domain for equality. Return 'Found if so, return 'NotFound if not.+-- The reason d'etre for this type family is that _open_ type families don't+-- allow overlapping types. We therefore defer equality checking to a closed+-- type family.+type DomEq (n :: Domain) (m :: Domain) =+  IfStuck (DomEqWorker n m) ('NotFound) (Pure (DomEqWorker n m))++-- | Type family that searches a type and checks whether a specific domain is+-- present. Will result in either "domain not found, and no others either",+-- "domain not found, but found another", or "found domain".+type family HasDomain (dom :: Domain) (n :: Type) :: HasDomainWrapperResult++type instance HasDomain dom1 (Proxy dom2)           = DomEq dom1 dom2+type instance HasDomain dom1 (Signal dom2 a)        = DomEq dom1 dom2+type instance HasDomain dom1 (DSignal dom2 delay a) = DomEq dom1 dom2+type instance HasDomain dom1 (Clock dom2)           = DomEq dom1 dom2+type instance HasDomain dom1 (Reset dom2)           = DomEq dom1 dom2+type instance HasDomain dom1 (Enable dom2)          = DomEq dom1 dom2+type instance HasDomain dom (Vec n a)               = HasDomain dom a+type instance HasDomain dom (a, b)                  = Merge dom a b+type instance HasDomain dom (a -> b)                = Merge dom a b++type family ErrOnNotFound (dom :: Domain) (n :: HasDomainWrapperResult) (t :: Type) :: Domain where+  ErrOnNotFound dom  'NotFound t = DelayError (NotFoundError dom t)+  ErrOnNotFound dom  'Found    t = dom++-- | Wrapper that checks for stuckness and returns "NotFound" if so+type family HasDomainWrapper (dom :: Domain) (n :: Type) :: HasDomainWrapperResult where+  HasDomainWrapper dom n =+    IfStuck+      (HasDomain dom n)+      ('NotFound)+      (Pure (HasDomain dom n))++-- | Helper function for HasSpecificDomain class (I don't really understand+-- why this one is necessary. HasDomainWrapper _should_ check for stuckness+-- and does so according to tests..+type family ResolveOrErr (dom :: Domain) (t :: Type) :: Domain where+  ResolveOrErr dom t =+    IfStuck+      (HasDomainWrapper dom t)+      (ErrOnNotFound dom 'NotFound t)+      (Pure (ErrOnNotFound dom (HasDomainWrapper dom t) t))++-- | Type class that specifies that a certain domain, /dom/, needs to be present+-- in some other type, /r/. This is used to disambiguate what hidden clock,+-- reset, and enable lines should be exposed in functions such as+-- 'withSpecificReset'.+--+-- Functions in need of this class should use 'WithSpecificDomain' though, to+-- force Clash to display an error instead of letting it silently pass.+class HasSpecificDomain (dom :: Domain) (r :: Type) where+  type GetDomain dom r :: Domain+  type GetDomain dom r = ResolveOrErr dom r++instance HasSpecificDomain dom a++mkHasDomainTuples ''HasDomain ''Merge
src/Clash/Class/Num.hs view
@@ -18,9 +18,11 @@     -- * Saturating arithmetic functions   , SaturationMode (..)   , SaturatingNum (..)-  , boundedPlus-  , boundedMin-  , boundedMult+  , boundedAdd+  , boundedSub+  , boundedMul+  , satSucc+  , satPred   ) where @@ -32,15 +34,15 @@   type AResult a b   -- | Add values of different (sub-)types, return a value of a (sub-)type   -- that is potentially different from either argument.-  plus  :: a -> b -> AResult a b+  add  :: a -> b -> AResult a b   -- | Subtract values of different (sub-)types, return a value of a (sub-)type   -- that is potentially different from either argument.-  minus :: a -> b -> AResult a b+  sub :: a -> b -> AResult a b   -- | Type of the result of the multiplication   type MResult a b   -- | Multiply values of different (sub-)types, return a value of a (sub-)type   -- that is potentially different from either argument.-  times :: a -> b -> MResult a b+  mul :: a -> b -> MResult a b  -- * Saturating arithmetic functions @@ -55,29 +57,39 @@                  -- numbers.   deriving Eq --- | 'Num' operators in which overflow and underflow behaviour can be specified+-- | 'Num' operators in which overflow and underflow behavior can be specified -- using 'SaturationMode'. class (Bounded a, Num a) => SaturatingNum a where-  -- | Addition with parametrisable over- and underflow behaviour-  satPlus :: SaturationMode -> a -> a -> a-  -- | Subtraction with parametrisable over- and underflow behaviour-  satMin  :: SaturationMode -> a -> a -> a-  -- | Multiplication with parametrisable over- and underflow behaviour-  satMult :: SaturationMode -> a -> a -> a+  -- | Addition with parameterizable over- and underflow behavior+  satAdd :: SaturationMode -> a -> a -> a+  -- | Subtraction with parameterizable over- and underflow behavior+  satSub  :: SaturationMode -> a -> a -> a+  -- | Multiplication with parameterizable over- and underflow behavior+  satMul :: SaturationMode -> a -> a -> a -{-# INLINE boundedPlus #-}+-- | Get successor of (or in other words, add 1 to) given number+satSucc :: SaturatingNum a => SaturationMode -> a -> a+satSucc s n = satAdd s n 1+{-# INLINE satSucc #-}++-- | Get predecessor of (or in other words, subtract 1 from) given number+satPred :: SaturatingNum a => SaturationMode -> a -> a+satPred s n = satSub s n 1+{-# INLINE satPred #-}+ -- | Addition that clips to 'maxBound' on overflow, and 'minBound' on underflow-boundedPlus :: SaturatingNum a => a -> a -> a-boundedPlus = satPlus SatBound+boundedAdd :: SaturatingNum a => a -> a -> a+boundedAdd = satAdd SatBound+{-# INLINE boundedAdd #-} -{-# INLINE boundedMin #-} -- | Subtraction that clips to 'maxBound' on overflow, and 'minBound' on -- underflow-boundedMin  :: SaturatingNum a => a -> a -> a-boundedMin = satMin SatBound+boundedSub  :: SaturatingNum a => a -> a -> a+boundedSub = satSub SatBound+{-# INLINE boundedSub #-} -{-# INLINE boundedMult #-} -- | Multiplication that clips to 'maxBound' on overflow, and 'minBound' on -- underflow-boundedMult :: SaturatingNum a => a -> a -> a-boundedMult = satMult SatBound+boundedMul :: SaturatingNum a => a -> a -> a+boundedMul = satMul SatBound+{-# INLINE boundedMul #-}
+ src/Clash/Clocks.hs view
@@ -0,0 +1,29 @@+{-|+Copyright  :  (C) 2018, Google Inc+                  2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++Generic clock related utilities.+-}++{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE FlexibleInstances   #-}+{-# LANGUAGE GADTs               #-}+{-# LANGUAGE TemplateHaskell     #-}+{-# LANGUAGE InstanceSigs        #-}+{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Clash.Clocks (Clocks, clocks) where++import Clash.Signal.Internal+import Clash.Clocks.Deriving (deriveClocksInstances)++class Clocks t where+  clocks+    :: Clock domIn+    -> Reset domIn+    -> t++deriveClocksInstances 16
+ src/Clash/Clocks/Deriving.hs view
@@ -0,0 +1,55 @@+{-|+Copyright  :  (C) 2018, Google Inc+                  2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE TemplateHaskell   #-}+{-# LANGUAGE QuasiQuotes       #-}+{-# LANGUAGE ViewPatterns      #-}++module Clash.Clocks.Deriving (deriveClocksInstances) where++import Control.Monad               (foldM)+import Clash.Signal.Internal+import Language.Haskell.TH.Syntax+import Language.Haskell.TH.Lib+import Unsafe.Coerce               (unsafeCoerce)++-- Derive instance for /n/ clocks+derive' :: Int -> Q Dec+derive' n = do+  -- (Clock d0, Clock d1, )+  instType  <- foldM (\a n' -> AppT a <$> clkType n') (TupleT $ n + 1) [1..n]+  instType' <- (AppT (ConT $ mkName "Clocks") . AppT instType) <$> lockType++  -- Function definition of 'clocks'+  let clk = mkName "clk"+  let rst = mkName "rst"++  -- Implementation of 'clocks'+  let noInline  = PragmaD $ InlineP (mkName "clocks") NoInline FunLike AllPhases+  let clkImpls  = replicate n (clkImpl clk)+  let instTuple = TupE $ clkImpls ++ [AppE (VarE 'unsafeCoerce) (VarE rst)]+  let funcBody  = NormalB instTuple+  let instFunc  = FunD (mkName "clocks") [Clause [VarP clk, VarP rst] funcBody []]++  return $ InstanceD Nothing [] instType' [instFunc, noInline]++  where+    -- | Generate type @Clock dom@ with fresh @dom@ variable+    clkType n' =+      let c = varT $ mkName ("c" ++ show n') in+      [t| Clock $c |]++    -- | Generate type @Signal dom 'Bool@ with fresh @dom@ variable+    lockType =+      let c = varT $ mkName "pllLock" in+      [t| Signal $c Bool |]++    clkImpl clk = AppE (VarE 'unsafeCoerce) (VarE clk)++-- Derive instances for up to and including to /n/ clocks+deriveClocksInstances :: Int -> Q [Dec]+deriveClocksInstances n = mapM derive' [1..n]
src/Clash/Examples.hs view
@@ -1,12 +1,13 @@ {-| Copyright : © 2015-2016, Christiaan Baaij,               2017     , Google Inc.+              2019     , Myrtle Software Ltd Licence   : Creative Commons 4.0 (CC BY 4.0) (http://creativecommons.org/licenses/by/4.0/) -}  {-# LANGUAGE NoImplicitPrelude, CPP, TemplateHaskell, DataKinds, BinaryLiterals,              FlexibleContexts, GADTs, TypeOperators, TypeApplications,-             RecordWildCards #-}+             RecordWildCards, DeriveGeneric, DeriveAnyClass #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-}@@ -81,8 +82,10 @@     0x8000 -> 0xF encoderCase _ _ = 0 -upCounter :: HiddenClockReset domain gated synchronous-          => Signal domain Bool -> Signal domain (Unsigned 8)+upCounter+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (Unsigned 8) upCounter enable = s   where     s = register 0 (mux enable (s + 1) s)@@ -95,12 +98,16 @@        | en        = s + 1        | otherwise = s -upCounterLd :: HiddenClockReset domain gated synchronous-            => Signal domain (Bool,Bool,Unsigned 8) -> Signal domain (Unsigned 8)+upCounterLd+  :: HiddenClockResetEnable dom+  => Signal dom (Bool, Bool, Unsigned 8)+  -> Signal dom (Unsigned 8) upCounterLd = mealy upCounterLdT 0 -upDownCounter :: HiddenClockReset domain gated synchronous-              => Signal domain Bool -> Signal domain (Unsigned 8)+upDownCounter+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (Unsigned 8) upDownCounter upDown = s   where     s = register 0 (mux upDown (s + 1) (s - 1))@@ -110,8 +117,9 @@   where     feedback = s!5 `xor` s!3 `xor` s!2 `xor` s!0 -lfsrF :: HiddenClockReset domain gated synchronous-      => BitVector 16 -> Signal domain Bit+lfsrF+  :: HiddenClockResetEnable dom+  => BitVector 16 -> Signal dom Bit lfsrF seed = msb <$> r   where r = register seed (lfsrF' <$> r) @@ -126,24 +134,36 @@     xorM i x | i         =  x `xor` fb              | otherwise = x -lfsrG :: HiddenClockReset domain gated synchronous => BitVector 16 -> Signal domain Bit+lfsrG+  :: HiddenClockResetEnable dom+  => BitVector 16+  -> Signal dom Bit lfsrG seed = last (unbundle r)   where r = register (unpack seed) (lfsrGP (unpack 0b0011010000000000) <$> r) -grayCounter :: HiddenClockReset domain gated synchronous-            => Signal domain Bool -> Signal domain (BitVector 8)+grayCounter+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (BitVector 8) grayCounter en = gray <$> upCounter en   where gray xs = pack (msb xs) ++# xor (slice d7 d1 xs) (slice d6 d0 xs) -oneHotCounter :: HiddenClockReset domain gated synchronous-              => Signal domain Bool -> Signal domain (BitVector 8)+oneHotCounter+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (BitVector 8) oneHotCounter enable = s   where     s = register 1 (mux enable (rotateL <$> s <*> 1) s)  crcT-  :: (Bits a, KnownNat (BitSize a), BitPack a)-  => a -> Bit -> a+  :: ( Bits a+     , KnownNat (BitSize a)+     , BitPack a+     )+  => a+  -> Bit+  -> a crcT bv dIn = replaceBit 0  dInXor             $ replaceBit 5  (bv!4  `xor` dInXor)             $ replaceBit 12 (bv!11 `xor` dInXor)@@ -153,8 +173,12 @@     rotated = rotateL bv 1     fb      = msb bv -crc :: HiddenClockReset domain gated synchronous-    => Signal domain Bool -> Signal domain Bool -> Signal domain Bit -> Signal domain (BitVector 16)+crc+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom Bool+  -> Signal dom Bit+  -> Signal dom (BitVector 16) crc enable ld dIn = s   where     s = register 0xFFFF (mux enable (mux ld 0xFFFF (crcT <$> s <*> dIn)) s)@@ -171,7 +195,7 @@   , _rx_d1         :: Bit   , _rx_d2         :: Bit   , _rx_busy       :: Bool-  }+  } deriving (Generic, NFDataX)  makeLenses ''RxReg @@ -183,6 +207,7 @@   , _tx_out      :: Bit   , _tx_cnt      :: Unsigned 4   }+  deriving (Generic, NFDataX)  makeLenses ''TxReg @@ -207,7 +232,7 @@     tx_cnt .= 0  uartRX r@(RxReg {..}) rx_in uld_rx_data rx_enable = flip execState r $ do-  -- Synchronise the async signal+  -- Synchronize the async signal   rx_d1 .= rx_in   rx_d2 .= _rx_d1   -- Uload the rx data@@ -369,9 +394,9 @@  @ upCounter-  :: HiddenClockReset domain gated synchronous-  => Signal domain Bool-  -> Signal domain (Unsigned 8)+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (Unsigned 8) upCounter enable = s   where     s = `register` 0 (`mux` enable (s + 1) s)@@ -383,9 +408,9 @@  @ upCounterLd-  :: HiddenClockReset domain gated synchronous-  => Signal domain (Bool,Bool,Unsigned 8)-  -> Signal domain (Unsigned 8)+  :: HiddenClockResetEnable dom+  => Signal dom (Bool,Bool,Unsigned 8)+  -> Signal dom (Unsigned 8) upCounterLd = `mealy` upCounterLdT 0  upCounterLdT s (ld,en,dIn) = (s',s)@@ -401,9 +426,9 @@  @ upDownCounter-  :: HiddenClockReset domain gated synchronous-  => Signal domain Bool-  -> Signal domain (Unsigned 8)+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (Unsigned 8) upDownCounter upDown = s   where     s = `register` 0 (`mux` upDown (s + 1) (s - 1))@@ -411,7 +436,7 @@  The following property holds: -prop> \en -> en ==> testFor 1000 (upCounter (pure en) .==. upDownCounter (pure en))+prop> \en -> en ==> testFor 1000 (upCounter (pure en) .==. upDownCounter (pure en) :: Signal "System" Bool)  = LFSR @@ -424,15 +449,15 @@     feedback = s'!'5 ``xor`` s'!'3 ``xor`` s'!'2 ``xor`` s'!'0  lfsrF-  :: HiddenClockReset domain gated synchronous+  :: HiddenClockResetEnable dom   => BitVector 16-  -> Signal domain Bit+  -> Signal dom Bit lfsrF seed = 'msb' '<$>' r   where r = 'register' seed (lfsrF' '<$>' r) @  We can also build a internal/Galois LFSR which has better timing characteristics.-We first define a Galois LFSR parametrizable in its filter taps:+We first define a Galois LFSR parameterizable in its filter taps:  @ lfsrGP taps regs = 'zipWith' xorM taps (fb '+>>' regs)@@ -445,14 +470,14 @@ Then we can instantiate a 16-bit LFSR as follows:  @-lfsrG :: HiddenClockReset domain gated synchronous => BitVector 16 -> Signal domain Bit+lfsrG :: HiddenClockResetEnable dom  => BitVector 16 -> Signal dom Bit lfsrG seed = 'last' ('unbundle' r)   where r = 'register' ('unpack' seed) (lfsrGP ('unpack' 0b0011010000000000) '<$>' r) @  The following property holds: -prop> testFor 100 (lfsrF 0xACE1 .==. lfsrG 0x4645)+prop> testFor 100 (lfsrF 0xACE1 .==. lfsrG 0x4645 :: Signal "System" Bool)  = Gray counter @@ -460,9 +485,9 @@  @ grayCounter-  :: HiddenClockReset domain gated synchronous-  => Signal domain Bool-  -> Signal domain (BitVector 8)+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (BitVector 8) grayCounter en = gray '<$>' upCounter en   where gray xs = 'pack' ('msb' xs) '++#' 'xor' ('slice' d7 d1 xs) ('slice' d6 d0 xs) @@@ -473,9 +498,9 @@  @ oneHotCounter-  :: HiddenClockReset domain gated synchronous-  => Signal domain Bool-  -> Signal domain (BitVector 8)+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom (BitVector 8) oneHotCounter enable = s   where     s = 'register' 1 ('mux' enable ('rotateL' '<$>' s '<*>' 1) s)@@ -512,11 +537,11 @@     fb      = 'msb' bv  crc-  :: HiddenClockReset domain gated synchronous-  => Signal domain Bool-  -> Signal domain Bool-  -> Signal domain Bit-  -> Signal domain (BitVector 16)+  :: HiddenClockResetEnable dom+  => Signal dom Bool+  -> Signal dom Bool+  -> Signal dom Bit+  -> Signal dom (BitVector 16) crc enable ld dIn = s   where     s = 'register' 0xFFFF ('mux' enable ('mux' ld 0xFFFF (crcT '<$>' s '<*>' dIn)) s)@@ -551,7 +576,7 @@ makeLenses ''RxReg  uartRX r\@(RxReg {..}) rx_in uld_rx_data rx_enable = 'flip' 'execState' r $ do-  -- Synchronise the async signal+  -- Synchronize the async signal   rx_d1 '.=' rx_in   rx_d2 '.=' _rx_d1   -- Uload the rx data
src/Clash/Explicit/BlockRam.hs view
@@ -12,13 +12,13 @@ We will show a rather elaborate example on how you can, and why you might want to use 'blockRam's. We will build a \"small\" CPU+Memory+Program ROM where we will slowly evolve to using blockRams. Note that the code is /not/ meant as a-de-facto standard on how to do CPU design in CλaSH.+de-facto standard on how to do CPU design in Clash.  We start with the definition of the Instructions, Register names and machine codes:  @-{\-\# LANGUAGE RecordWildCards, TupleSections \#-\}+{\-\# LANGUAGE RecordWildCards, TupleSections, DeriveAnyClass \#-\} module CPU where  import Clash.Explicit.Prelude@@ -120,15 +120,17 @@  @ dataMem-  :: Clock domain gated-  -> Reset domain synchronous-  -> Signal domain MemAddr+  :: KnownDomain dom+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom MemAddr   -- ^ Read address-  -> Signal domain (Maybe (MemAddr,Value))+  -> Signal dom (Maybe (MemAddr,Value))   -- ^ (write address, data in)-  -> Signal domain Value+  -> Signal dom Value   -- ^ data out-dataMem clk rst rd wrM = 'Clash.Explicit.Mealy.mealy' clk rst dataMemT ('Clash.Sized.Vector.replicate' d32 0) (bundle (rd,wrM))+dataMem clk rst en rd wrM = 'Clash.Explicit.Mealy.mealy' clk rst en dataMemT ('Clash.Sized.Vector.replicate' d32 0) (bundle (rd,wrM))   where     dataMemT mem (rd,wrM) = (mem',dout)       where@@ -142,15 +144,17 @@  @ system-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system instrs clk rst en = memOut   where-    memOut = dataMem clk rst rdAddr dout-    (rdAddr,dout,ipntr) = 'Clash.Explicit.Mealy.mealyB' clk rst cpu ('Clash.Sized.Vector.replicate' d7 0) (memOut,instr)+    memOut = dataMem clk rst en rdAddr dout+    (rdAddr,dout,ipntr) = 'Clash.Explicit.Mealy.mealyB' clk rst en cpu ('Clash.Sized.Vector.replicate' d7 0) (memOut,instr)     instr  = 'Clash.Explicit.Prelude.asyncRom' instrs '<$>' ipntr @ @@ -191,8 +195,8 @@ And test our system:  @->>> sampleN 31 $ system prog systemClockGen systemResetGen-[0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> sampleN 32 $ system prog systemClockGen resetGen enableGen+[0,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -209,15 +213,17 @@  @ system2-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system2 instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system2 instrs clk rst en = memOut   where-    memOut = 'Clash.Explicit.RAM.asyncRam' clk clk d32 rdAddr dout-    (rdAddr,dout,ipntr) = 'mealyB' clk rst cpu ('Clash.Sized.Vector.replicate' d7 0) (memOut,instr)+    memOut = 'Clash.Explicit.RAM.asyncRam' clk clk en d32 rdAddr dout+    (rdAddr,dout,ipntr) = 'mealyB' clk rst en cpu ('Clash.Sized.Vector.replicate' d7 0) (memOut,instr)     instr  = 'Clash.Prelude.ROM.asyncRom' instrs '<$>' ipntr @ @@ -228,8 +234,8 @@ filter out the undefinedness and replace it with the string "X" in the few leading outputs.  @->>> printX $ sampleN 31 $ system2 prog systemClockGen systemResetGen-[X,X,X,X,X,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> printX $ sampleN 32 $ system2 prog systemClockGen resetGen enableGen+[X,X,X,X,X,X,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -242,7 +248,7 @@ 'blockRam' function will be translated to such a /Block RAM/.  One important aspect of Block RAMs have a /synchronous/ read port, meaning that,-unlike the behaviour of 'Clash.Prelude.RAM.asyncRam', given a read address @r@+unlike the behavior of 'Clash.Prelude.RAM.asyncRam', given a read address @r@ at time @t@, the value @v@ in the RAM at address @r@ is only available at time @t+1@. @@ -299,15 +305,17 @@  @ system3-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system3 instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system3 instrs clk rst en = memOut   where-    memOut = 'blockRam' clk (replicate d32 0) rdAddr dout-    (rdAddr,dout,ipntr) = 'mealyB' clk rst cpu2 (('Clash.Sized.Vector.replicate' d7 0),Zero) (memOut,instr)+    memOut = 'blockRam' clk en (replicate d32 0) rdAddr dout+    (rdAddr,dout,ipntr) = 'mealyB' clk rst en cpu2 (('Clash.Sized.Vector.replicate' d7 0),Zero) (memOut,instr)     instr  = 'Clash.Explicit.Prelude.asyncRom' instrs '<$>' ipntr @ @@ -356,8 +364,8 @@ filter out the undefinedness and replace it with the string "X".  @->>> printX $ sampleN 33 $ system3 prog2 systemClockGen systemResetGen-[X,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> printX $ sampleN 34 $ system3 prog2 systemClockGen resetGen enableGen+[X,0,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -368,8 +376,10 @@ {-# LANGUAGE BangPatterns        #-} {-# LANGUAGE DataKinds           #-} {-# LANGUAGE GADTs               #-}+{-# LANGUAGE KindSignatures      #-} {-# LANGUAGE MagicHash           #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-} {-# LANGUAGE TypeOperators       #-}  {-# LANGUAGE Trustworthy #-}@@ -382,9 +392,12 @@ {-# OPTIONS_GHC -fno-cpr-anal #-}  module Clash.Explicit.BlockRam-  ( -- * BlockRAM synchronised to the system clock+  ( -- * BlockRAM synchronized to the system clock     blockRam   , blockRamPow2+  , blockRamU+  , blockRam1+  , ResetStrategy(..)     -- * Read/Write conflict resolution   , readNew     -- * Internal@@ -392,23 +405,31 @@   ) where -import Data.Maybe             (fromJust, isJust)+import           Data.Maybe             (isJust) import qualified Data.Vector  as V-import GHC.Stack              (HasCallStack, withFrozenCallStack)-import GHC.TypeLits           (KnownNat, type (^))-import Prelude                hiding (length)+import           GHC.Stack              (HasCallStack, withFrozenCallStack)+import           GHC.TypeLits           (KnownNat, type (^), type (<=))+import           Prelude                hiding (length, replicate) -import Clash.Signal.Internal-  (Clock, Reset, Signal (..), (.&&.), clockEnable, mux, register#)-import Clash.Signal.Bundle    (unbundle)-import Clash.Sized.Unsigned   (Unsigned)-import Clash.Sized.Vector     (Vec, toList)-import Clash.XException       (errorX, maybeX, seqX)+import           Clash.Annotations.Primitive+  (hasBlackBox)+import           Clash.Class.Num        (SaturationMode(SatBound), satSucc)+import           Clash.Explicit.Signal  (KnownDomain, Enable, register, fromEnable)+import           Clash.Signal.Internal+  (Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)+import           Clash.Promoted.Nat     (SNat(..))+import           Clash.Signal.Bundle    (unbundle)+import           Clash.Sized.Unsigned   (Unsigned)+import           Clash.Sized.Index      (Index)+import           Clash.Sized.Vector     (Vec, replicate, toList, iterateI)+import qualified Clash.Sized.Vector     as CV+import           Clash.XException+  (maybeIsX, seqX, NFDataX, deepErrorX, defaultSeqX, errorX)  {- $setup >>> import Clash.Explicit.Prelude as C >>> import qualified Data.List as L->>> :set -XDataKinds -XRecordWildCards -XTupleSections+>>> :set -XDataKinds -XRecordWildCards -XTupleSections -XDeriveAnyClass -XDeriveGeneric >>> type InstrAddr = Unsigned 8 >>> type MemAddr = Unsigned 5 >>> type Value = Signed 8@@ -421,7 +442,7 @@   | RegC   | RegD   | RegE-  deriving (Eq,Show,Enum)+  deriving (Eq,Show,Enum,C.Generic,NFDataX) :}  >>> :{@@ -505,12 +526,14 @@  >>> :{ dataMem-  :: Clock  domain gated-  -> Reset  domain synchronous-  -> Signal domain MemAddr-  -> Signal domain (Maybe (MemAddr,Value))-  -> Signal domain Value-dataMem clk rst rd wrM = mealy clk rst dataMemT (C.replicate d32 0) (bundle (rd,wrM))+  :: KnownDomain dom+  => Clock  dom+  -> Reset  dom+  -> Enable dom+  -> Signal dom MemAddr+  -> Signal dom (Maybe (MemAddr,Value))+  -> Signal dom Value+dataMem clk rst en rd wrM = mealy clk rst en dataMemT (C.replicate d32 0) (bundle (rd,wrM))   where     dataMemT mem (rd,wrM) = (mem',dout)       where@@ -522,15 +545,17 @@  >>> :{ system-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system instrs clk rst en = memOut   where-    memOut = dataMem clk rst rdAddr dout-    (rdAddr,dout,ipntr) = mealyB clk rst cpu (C.replicate d7 0) (memOut,instr)+    memOut = dataMem clk rst en rdAddr dout+    (rdAddr,dout,ipntr) = mealyB clk rst en cpu (C.replicate d7 0) (memOut,instr)     instr  = asyncRom instrs <$> ipntr :} @@ -568,15 +593,17 @@  >>> :{ system2-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system2 instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system2 instrs clk rst en = memOut   where-    memOut = asyncRam clk clk d32 rdAddr dout-    (rdAddr,dout,ipntr) = mealyB clk rst cpu (C.replicate d7 0) (memOut,instr)+    memOut = asyncRam clk clk en d32 rdAddr dout+    (rdAddr,dout,ipntr) = mealyB clk rst en cpu (C.replicate d7 0) (memOut,instr)     instr  = asyncRom instrs <$> ipntr :} @@ -617,15 +644,17 @@  >>> :{ system3-  :: KnownNat n+  :: ( KnownDomain dom+     , KnownNat n )   => Vec n Instruction-  -> Clock domain gated-  -> Reset domain synchronous-  -> Signal domain Value-system3 instrs clk rst = memOut+  -> Clock dom+  -> Reset dom+  -> Enable dom+  -> Signal dom Value+system3 instrs clk rst en = memOut   where-    memOut = blockRam clk (C.replicate d32 0) rdAddr dout-    (rdAddr,dout,ipntr) = mealyB clk rst cpu2 ((C.replicate d7 0),Zero) (memOut,instr)+    memOut = blockRam clk en (C.replicate d32 0) rdAddr dout+    (rdAddr,dout,ipntr) = mealyB clk rst en cpu2 ((C.replicate d7 0),Zero) (memOut,instr)     instr  = asyncRom instrs <$> ipntr :} @@ -663,17 +692,23 @@  -} +fromJustX :: HasCallStack => Maybe a -> a+fromJustX Nothing  = errorX "fromJustX: Nothing"+fromJustX (Just x) = x+ -- | Create a blockRAM with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle -- * __NB__: Initial output value is 'undefined' -- -- @--- bram40 :: 'Clock'  domain gated---        -> 'Signal' domain ('Unsigned' 6)---        -> 'Signal' domain (Maybe ('Unsigned' 6, 'Clash.Sized.BitVector.Bit'))---        -> 'Signal' domain 'Clash.Sized.BitVector.Bit'--- bram40 clk = 'blockRam' clk ('Clash.Sized.Vector.replicate' d40 1)+-- bram40+--   :: 'Clock'  dom+--   -> 'Enable'  dom+--   -> 'Signal' dom ('Unsigned' 6)+--   -> 'Signal' dom (Maybe ('Unsigned' 6, 'Clash.Sized.BitVector.Bit'))+--   -> 'Signal' dom 'Clash.Sized.BitVector.Bit'+-- bram40 clk en = 'blockRam' clk en ('Clash.Sized.Vector.replicate' d40 1) -- @ -- -- Additional helpful information:@@ -682,10 +717,14 @@ -- Block RAM. -- * Use the adapter 'readNew' for obtaining write-before-read semantics like this: @'readNew' clk rst ('blockRam' clk inits) rd wrM@. blockRam-  :: HasCallStack-  => Enum addr-  => Clock dom gated+  :: ( KnownDomain dom+     , HasCallStack+     , NFDataX a+     , Enum addr )+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> Vec n a   -- ^ Initial content of the BRAM, also determines the size, @n@, of the BRAM.    --@@ -696,11 +735,11 @@   -- ^ (write address @w@, value to write)   -> Signal dom a   -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle-blockRam = \clk content rd wrM ->+blockRam = \clk gen content rd wrM ->   let en       = isJust <$> wrM-      (wr,din) = unbundle (fromJust <$> wrM)+      (wr,din) = unbundle (fromJustX <$> wrM)   in  withFrozenCallStack-      (blockRam# clk content (fromEnum <$> rd) en (fromEnum <$> wr) din)+      (blockRam# clk gen content (fromEnum <$> rd) en (fromEnum <$> wr) din) {-# INLINE blockRam #-}  -- | Create a blockRAM with space for 2^@n@ elements@@ -709,10 +748,13 @@ -- * __NB__: Initial output value is 'undefined' -- -- @--- bram32 :: 'Signal' domain ('Unsigned' 5)---        -> 'Signal' domain (Maybe ('Unsigned' 5, 'Clash.Sized.BitVector.Bit'))---        -> 'Signal' domain 'Clash.Sized.BitVector.Bit'--- bram32 clk = 'blockRamPow2' clk ('Clash.Sized.Vector.replicate' d32 1)+-- bram32+--   :: 'Clock' dom+--   -> 'Enable' dom+--   -> 'Signal' dom ('Unsigned' 5)+--   -> 'Signal' dom (Maybe ('Unsigned' 5, 'Clash.Sized.BitVector.Bit'))+--   -> 'Signal' dom 'Clash.Sized.BitVector.Bit'+-- bram32 clk en = 'blockRamPow2' clk en ('Clash.Sized.Vector.replicate' d32 1) -- @ -- -- Additional helpful information:@@ -721,86 +763,282 @@ -- Block RAM. -- * Use the adapter 'readNew' for obtaining write-before-read semantics like this: @'readNew' clk rst ('blockRamPow2' clk inits) rd wrM@. blockRamPow2-  :: (KnownNat n, HasCallStack)-  => Clock dom gated          -- ^ 'Clock' to synchronize to-  -> Vec (2^n) a              -- ^ Initial content of the BRAM, also-                              -- determines the size, @2^n@, of-                              -- the BRAM.-                              ---                              -- __NB__: __MUST__ be a constant.-  -> Signal dom (Unsigned n) -- ^ Read address @r@+  :: ( KnownDomain dom+     , HasCallStack+     , NFDataX a+     , KnownNat n )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> Vec (2^n) a+  -- ^ Initial content of the BRAM, also+  -- determines the size, @2^n@, of+  -- the BRAM.+  --+  -- __NB__: __MUST__ be a constant.+  -> Signal dom (Unsigned n)+  -- ^ Read address @r@   -> Signal dom (Maybe (Unsigned n, a))   -- ^ (Write address @w@, value to write)   -> Signal dom a   -- ^ Value of the @blockRAM@ at address @r@ from the previous   -- clock cycle-blockRamPow2 = \clk cnt rd wrM -> withFrozenCallStack-  (blockRam clk cnt rd wrM)+blockRamPow2 = \clk en cnt rd wrM -> withFrozenCallStack+  (blockRam clk en cnt rd wrM) {-# INLINE blockRamPow2 #-} +data ResetStrategy (r :: Bool) where+  ClearOnReset :: ResetStrategy 'True+  NoClearOnReset :: ResetStrategy 'False++-- | Version of blockram that has no default values set. May be cleared to a+-- arbitrary state using a reset function.+blockRamU+   :: forall n dom a r addr+   . ( KnownDomain dom+     , HasCallStack+     , NFDataX a+     , Enum addr+     , 1 <= n )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Reset dom+  -- ^ 'Reset' line to listen to. Needs to be held at least /n/ cycles in order+  -- for the BRAM to be reset to its initial state.+  -> Enable dom+  -- ^ Global enable+  -> ResetStrategy r+  -- ^ Whether to clear BRAM on asserted reset ('ClearOnReset') or+  -- not ('NoClearOnReset'). Reset needs to be asserted at least /n/ cycles to+  -- clear the BRAM.+  -> SNat n+  -- ^ Number of elements in BRAM+  -> (Index n -> a)+  -- ^ If applicable (see first argument), reset BRAM using this function.+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))+  -- ^ (write address @w@, value to write)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRamU clk rst0 en rstStrategy n@SNat initF rd0 mw0 =+  case rstStrategy of+    ClearOnReset ->+      -- Use reset infrastructure+      blockRamU# clk en n rd1 we1 wa1 w1+    NoClearOnReset ->+      -- Ignore reset infrastructure, pass values unchanged+      blockRamU# clk en n+        (fromEnum <$> rd0)+        we0+        (fromEnum <$> wa0)+        w0+ where+  rstBool = register clk rst0 en True (pure False)+  rstInv = invertReset rst0++  waCounter :: Signal dom (Index n)+  waCounter = register clk rstInv en 0 (satSucc SatBound <$> waCounter)++  wa0 = fst . fromJustX <$> mw0+  w0  = snd . fromJustX <$> mw0+  we0 = isJust <$> mw0++  rd1 = mux rstBool 0 (fromEnum <$> rd0)+  we1 = mux rstBool (pure True) we0+  wa1 = mux rstBool (fromInteger . toInteger <$> waCounter) (fromEnum <$> wa0)+  w1  = mux rstBool (initF <$> waCounter) w0++-- | blockRAM1 primitive+blockRamU#+  :: forall n dom a+   . ( KnownDomain dom+     , HasCallStack+     , NFDataX a )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global Enable+  -> SNat n+  -- ^ Number of elements in BRAM+  -> Signal dom Int+  -- ^ Read address @r@+  -> Signal dom Bool+  -- ^ Write enable+  -> Signal dom Int+  -- ^ Write address @w@+  -> Signal dom a+  -- ^ Value to write (at address @w@)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRamU# clk en SNat =+  -- TODO: Generalize to single BRAM primitive taking an initialization function+  blockRam#+    clk+    en+    (CV.map+      (\i -> deepErrorX $ "Initial value at index " ++ show i ++ " undefined.")+      (iterateI @n succ (0 :: Int)))+{-# NOINLINE blockRamU# #-}+{-# ANN blockRamU# hasBlackBox #-}++-- | Version of blockram that is initialized with the same value on all+-- memory positions.+blockRam1+   :: forall n dom a r addr+   . ( KnownDomain dom+     , HasCallStack+     , NFDataX a+     , Enum addr+     , 1 <= n )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Reset dom+  -- ^ 'Reset' line to listen to. Needs to be held at least /n/ cycles in order+  -- for the BRAM to be reset to its initial state.+  -> Enable dom+  -- ^ Global enable+  -> ResetStrategy r+  -- ^ Whether to clear BRAM on asserted reset ('ClearOnReset') or+  -- not ('NoClearOnReset'). Reset needs to be asserted at least /n/ cycles to+  -- clear the BRAM.+  -> SNat n+  -- ^ Number of elements in BRAM+  -> a+  -- ^ Initial content of the BRAM (replicated /n/ times)+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))+  -- ^ (write address @w@, value to write)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRam1 clk rst0 en rstStrategy n@SNat a rd0 mw0 =+  case rstStrategy of+    ClearOnReset ->+      -- Use reset infrastructure+      blockRam1# clk en n a rd1 we1 wa1 w1+    NoClearOnReset ->+      -- Ignore reset infrastructure, pass values unchanged+      blockRam1# clk en n a+        (fromEnum <$> rd0)+        we0+        (fromEnum <$> wa0)+        w0+ where+  rstBool = register clk rst0 en True (pure False)+  rstInv = invertReset rst0++  waCounter :: Signal dom (Index n)+  waCounter = register clk rstInv en 0 (satSucc SatBound <$> waCounter)++  wa0 = fst . fromJustX <$> mw0+  w0  = snd . fromJustX <$> mw0+  we0 = isJust <$> mw0++  rd1 = mux rstBool 0 (fromEnum <$> rd0)+  we1 = mux rstBool (pure True) we0+  wa1 = mux rstBool (fromInteger . toInteger <$> waCounter) (fromEnum <$> wa0)+  w1  = mux rstBool (pure a) w0++-- | blockRAM1 primitive+blockRam1#+  :: forall n dom a+   . ( KnownDomain dom+     , HasCallStack+     , NFDataX a )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global Enable+  -> SNat n+  -- ^ Number of elements in BRAM+  -> a+  -- ^ Initial content of the BRAM (replicated /n/ times)+  -> Signal dom Int+  -- ^ Read address @r@+  -> Signal dom Bool+  -- ^ Write enable+  -> Signal dom Int+  -- ^ Write address @w@+  -> Signal dom a+  -- ^ Value to write (at address @w@)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRam1# clk en n a =+  -- TODO: Generalize to single BRAM primitive taking an initialization function+  blockRam# clk en (replicate n a)+{-# NOINLINE blockRam1# #-}+{-# ANN blockRam1# hasBlackBox #-}+ -- | blockRAM primitive blockRam#-  :: HasCallStack-  => Clock dom gated -- ^ 'Clock' to synchronize to-  -> Vec n a         -- ^ Initial content of the BRAM, also-                     -- determines the size, @n@, of the BRAM.-                     ---                     -- __NB__: __MUST__ be a constant.-  -> Signal dom Int  -- ^ Read address @r@-  -> Signal dom Bool -- ^ Write enable-  -> Signal dom Int  -- ^ Write address @w@-  -> Signal dom a    -- ^ Value to write (at address @w@)+  :: ( KnownDomain dom+     , HasCallStack+     , NFDataX a )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> Vec n a+  -- ^ Initial content of the BRAM, also+  -- determines the size, @n@, of the BRAM.+  --+  -- __NB__: __MUST__ be a constant.+  -> Signal dom Int+  -- ^ Read address @r@+  -> Signal dom Bool+  -- ^ Write enable+  -> Signal dom Int+  -- ^ Write address @w@   -> Signal dom a-  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock-  -- cycle-blockRam# clk content rd wen = case clockEnable clk of-  Nothing ->-    go (V.fromList (toList content))-       (withFrozenCallStack (errorX "blockRam: intial value undefined"))-       rd wen-  Just ena ->-    go' (V.fromList (toList content))-       (withFrozenCallStack (errorX "blockRam: intial value undefined"))-       ena rd (ena .&&. wen)-  where-    -- no clock enable-    go !ram o (r :- rs) (e :- en) (w :- wr) (d :- din) =-      let ram' = upd ram e (fromEnum w) d-          o'   = ram V.! r-      in  o `seqX` o :- go ram' o' rs en wr din-    -- clock enable-    go' !ram o (re :- res) (r :- rs) (e :- en) (w :- wr) (d :- din) =-      let ram' = upd ram e (fromEnum w) d-          o'   = if re then ram V.! r else o-      in  o `seqX` o :- go' ram' o' res rs en wr din+  -- ^ Value to write (at address @w@)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRam# (Clock _) gen content rd wen =+  go+    (V.fromList (toList content))+    (withFrozenCallStack (deepErrorX "blockRam: intial value undefined"))+    (fromEnable gen)+    rd+    (fromEnable gen .&&. wen)+ where+  go !ram o ret@(~(re :- res)) rt@(~(r :- rs)) et@(~(e :- en)) wt@(~(w :- wr)) dt@(~(d :- din)) =+    let ram' = d `defaultSeqX` upd ram e (fromEnum w) d+        o'   = if re then ram V.! r else o+    in  o `seqX` o :- (ret `seq` rt `seq` et `seq` wt `seq` dt `seq` go ram' o' res rs en wr din) -    upd ram we waddr d = case maybeX we of-      Nothing -> case maybeX waddr of-        Nothing -> V.map (const (seq waddr d)) ram-        Just wa -> ram V.// [(wa,d)]-      Just True -> case maybeX waddr of-        Nothing -> V.map (const (seq waddr d)) ram-        Just wa -> ram V.// [(wa,d)]-      _ -> ram+  upd ram we waddr d = case maybeIsX we of+    Nothing -> case maybeIsX waddr of+      Nothing -> V.map (const (seq waddr d)) ram+      Just wa -> ram V.// [(wa,d)]+    Just True -> case maybeIsX waddr of+      Nothing -> V.map (const (seq waddr d)) ram+      Just wa -> ram V.// [(wa,d)]+    _ -> ram+{-# ANN blockRam# hasBlackBox #-} {-# NOINLINE blockRam# #-}  -- | Create read-after-write blockRAM from a read-before-write one readNew-  :: Eq addr-  => Reset domain synchronous-  -> Clock domain gated-  -> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a)+  :: ( KnownDomain dom+     , NFDataX a+     , Eq addr )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a)   -- ^ The @ram@ component-  -> Signal domain addr+  -> Signal dom addr   -- ^ Read address @r@-  -> Signal domain (Maybe (addr, a))+  -> Signal dom (Maybe (addr, a))   -- ^ (Write address @w@, value to write)-  -> Signal domain a+  -> Signal dom a   -- ^ Value of the @ram@ at address @r@ from the previous clock cycle-readNew rst clk ram rdAddr wrM = mux wasSame wasWritten $ ram rdAddr wrM+readNew clk rst en ram rdAddr wrM = mux wasSame wasWritten $ ram rdAddr wrM   where readNewT rd (Just (wr, wrdata)) = (wr == rd, wrdata)         readNewT _  Nothing             = (False   , undefined)          (wasSame,wasWritten) =-          unbundle (register# clk rst (False,undefined)-                              (readNewT <$> rdAddr <*> wrM))+          unbundle (register clk rst en (False, undefined)+                             (readNewT <$> rdAddr <*> wrM))
src/Clash/Explicit/BlockRam/File.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -= Initialising a BlockRAM with a data file #usingramfiles#+= Initializing a BlockRAM with a data file #usingramfiles# -BlockRAM primitives that can be initialised with a data file. The BNF grammar+BlockRAM primitives that can be initialized with a data file. The BNF grammar for this data file is simple:  @@@ -34,9 +35,9 @@  @ f-  :: Clock  domain gated-  -> Signal domain (Unsigned 3)-  -> Signal domain (Unsigned 9)+  :: Clock  dom+  -> Signal dom (Unsigned 3)+  -> Signal dom (Unsigned 9) f clk rd = 'Clash.Class.BitPack.unpack' '<$>' 'blockRamFile' clk d7 \"memory.bin\" rd (signal Nothing) @ @@ -54,9 +55,9 @@  @ g-  :: Clock  domain Source-  -> Signal domain (Unsigned 3)-  -> Signal domain (Unsigned 6,Signed 3)+  :: Clock  dom+  -> Signal dom (Unsigned 3)+  -> Signal dom (Unsigned 6,Signed 3) g clk rd = 'Clash.Class.BitPack.unpack' '<$>' 'blockRamFile' clk d7 \"memory.bin\" rd (signal Nothing) @ @@ -88,7 +89,7 @@ {-# OPTIONS_GHC -fno-cpr-anal #-}  module Clash.Explicit.BlockRam.File-  ( -- * BlockRAM synchronised to an arbitrary clock+  ( -- * BlockRAM synchronized to an arbitrary clock     blockRamFile   , blockRamFilePow2     -- * Internal@@ -107,10 +108,11 @@  import Clash.Promoted.Nat    (SNat (..), pow2SNat) import Clash.Sized.BitVector (BitVector)-import Clash.Signal.Internal (Clock, Signal (..), (.&&.), clockEnable)+import Clash.Signal.Internal+  (Clock(..), Signal (..), Enable, KnownDomain, fromEnable, (.&&.)) import Clash.Signal.Bundle   (unbundle) import Clash.Sized.Unsigned  (Unsigned)-import Clash.XException      (errorX, maybeX, seqX)+import Clash.XException      (errorX, maybeIsX, seqX)   -- | Create a blockRAM with space for 2^@n@ elements@@ -134,25 +136,28 @@ -- -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- Block RAM.--- * Use the adapter 'readNew'' for obtaining write-before-read semantics like this: @readNew' clk (blockRamFilePow2' clk file) rd wrM@.+-- * Use the adapter 'Clash.Explicit.BlockRam.readNew' for obtaining write-before-read semantics like this: @'Clash.Explicit.BlockRam.readNew' clk rst en (blockRamFilePow2' clk en file) rd wrM@. -- * See "Clash.Explicit.BlockRam.File#usingramfiles" for more information on how -- to instantiate a Block RAM with the contents of a data file. -- * See "Clash.Explicit.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. blockRamFilePow2-  :: forall dom gated n m-   . (KnownNat m, KnownNat n, HasCallStack)-  => Clock dom gated+  :: forall dom n m+   . (KnownDomain dom, KnownNat m, KnownNat n, HasCallStack)+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> FilePath   -- ^ File describing the initial content of the blockRAM-  -> Signal dom (Unsigned n)  -- ^ Read address @r@+  -> Signal dom (Unsigned n)+  -- ^ Read address @r@   -> Signal dom (Maybe (Unsigned n, BitVector m))   -- ^ (write address @w@, value to write)   -> Signal dom (BitVector m)   -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle-blockRamFilePow2 = \clk file rd wrM -> withFrozenCallStack-  (blockRamFile clk (pow2SNat (SNat @ n)) file rd wrM)+blockRamFilePow2 = \clk en file rd wrM -> withFrozenCallStack+  (blockRamFile clk en (pow2SNat (SNat @ n)) file rd wrM) {-# INLINE blockRamFilePow2 #-}  -- | Create a blockRAM with space for @n@ elements@@ -176,15 +181,17 @@ -- -- * See "Clash.Explicit.BlockRam#usingrams" for more information on how to use a -- Block RAM.--- * Use the adapter 'readNew'' for obtaining write-before-read semantics like this: @readNew' clk (blockRamFile' clk size file) rd wrM@.+-- * Use the adapter 'Clash.Explicit.BlockRam.readNew' for obtaining write-before-read semantics like this: @'Clash.Explicit.BlockRam.readNew' clk rst en ('blockRamFile' clk en size file) rd wrM@. -- * See "Clash.Explicit.BlockRam.File#usingramfiles" for more information on how -- to instantiate a Block RAM with the contents of a data file. -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. blockRamFile-  :: (KnownNat m, Enum addr, HasCallStack)-  => Clock dom gated+  :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack)+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> SNat n   -- ^ Size of the blockRAM   -> FilePath@@ -196,18 +203,21 @@   -> Signal dom (BitVector m)   -- ^ Value of the @blockRAM@ at address @r@ from the previous   -- clock cycle-blockRamFile = \clk sz file rd wrM ->+blockRamFile = \clk gen sz file rd wrM ->   let en       = isJust <$> wrM       (wr,din) = unbundle (fromJust <$> wrM)   in  withFrozenCallStack-      (blockRamFile# clk sz file (fromEnum <$> rd) en (fromEnum <$> wr) din)+      (blockRamFile# clk gen sz file (fromEnum <$> rd) en (fromEnum <$> wr) din) {-# INLINE blockRamFile #-}  -- | blockRamFile primitive blockRamFile#-  :: (KnownNat m, HasCallStack)-  => Clock dom gated+  :: forall m dom n+   . (KnownDomain dom, KnownNat m, HasCallStack)+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> SNat n   -- ^ Size of the blockRAM   -> FilePath@@ -222,41 +232,45 @@   -- ^ Value to write (at address @w@)   -> Signal dom (BitVector m)   -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle-blockRamFile# clk _sz file rd wen = case clockEnable clk of-  Nothing ->-    go ramI-       (withFrozenCallStack (errorX "blockRamFile#: intial value undefined"))-       rd wen-  Just ena ->-    go' ramI-       (withFrozenCallStack (errorX "blockRamFile#: intial value undefined"))-       ena rd (ena .&&. wen)+blockRamFile# (Clock _) ena _sz file rd wen =+  go+    ramI+    (withFrozenCallStack (errorX "blockRamFile#: intial value undefined"))+    (fromEnable ena)+    rd+    (fromEnable ena .&&. wen)   where-    -- no clock enable-    go !ram o (r :- rs) (e :- en) (w :- wr) (d :- din) =-      let ram' = upd ram e (fromEnum w) d-          o'   = ram V.! r-      in  o `seqX` o :- go ram' o' rs en wr din     -- clock enable-    go' !ram o (re :- res) (r :- rs) (e :- en) (w :- wr) (d :- din) =+    go+      :: V.Vector (BitVector m)+      -> BitVector m+      -> Signal dom Bool+      -> Signal dom Int+      -> Signal dom Bool+      -> Signal dom Int+      -> Signal dom (BitVector m)+      -> Signal dom (BitVector m)+    go !ram o (re :- res) (r :- rs) (e :- en) (w :- wr) (d :- din) =       let ram' = upd ram e (fromEnum w) d           o'   = if re then ram V.! r else o-      in  o `seqX` o :- go' ram' o' res rs en wr din+      in  o `seqX` o :- go ram' o' res rs en wr din -    upd ram we waddr d = case maybeX we of-      Nothing -> case maybeX waddr of+    upd ram we waddr d = case maybeIsX we of+      Nothing -> case maybeIsX waddr of         Nothing -> V.map (const (seq waddr d)) ram         Just wa -> ram V.// [(wa,d)]-      Just True -> case maybeX waddr of+      Just True -> case maybeIsX waddr of         Nothing -> V.map (const (seq waddr d)) ram         Just wa -> ram V.// [(wa,d)]       _ -> ram      content = unsafePerformIO (initMem file)-    ramI    = V.fromList content++    ramI :: V.Vector (BitVector m)+    ramI = V.fromList content {-# NOINLINE blockRamFile# #-} --- | __NB:__ Not synthesisable+-- | __NB:__ Not synthesizable initMem :: KnownNat n => FilePath -> IO [BitVector n] initMem = fmap (map parseBV . lines) . readFile   where
src/Clash/Explicit/DDR.hs view
@@ -1,27 +1,35 @@ {-| Copyright  :  (C) 2017, Google Inc+                  2019, Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  We simulate DDR signal by using 'Signal's which have exactly half the period (or double the speed) of our normal 'Signal's. -The primives in this module can be used to produce of consume DDR signals.+The primitives in this module can be used to produce of consume DDR signals.  DDR signals are not meant to be used internally in a design, but only to communicate with the outside world. -In some cases hardware specific DDR IN registers can be infered by synthesis tools-from these generic primitives. But to be sure your design will synthesize to-dedicated hardware resources use the functions from "Clash.Intel.DDR"+In some cases hardware specific DDR IN registers can be inferred by synthesis+tools from these generic primitives. But to be sure your design will synthesize+to dedicated hardware resources use the functions from "Clash.Intel.DDR" or "Clash.Xilinx.DDR". -} +{-# LANGUAGE CPP                 #-} {-# LANGUAGE DataKinds           #-}+{-# LANGUAGE FlexibleContexts    #-} {-# LANGUAGE MagicHash           #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-} {-# LANGUAGE TypeFamilies        #-} {-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE ViewPatterns        #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  module Clash.Explicit.DDR   ( ddrIn@@ -34,6 +42,7 @@  import GHC.Stack (HasCallStack, withFrozenCallStack) +import Clash.Annotations.Primitive    (hasBlackBox) import Clash.Explicit.Prelude import Clash.Signal.Internal @@ -42,112 +51,126 @@ -- -- Consumes a DDR input signal and produces a regular signal containing a pair -- of values.+--+-- >>> printX $ sampleN 5 $ ddrIn systemClockGen resetGen enableGen (-1,-2,-3) (fromList [0..10])+-- [(X,X),((-1),(-2)),((-3),2),(3,4),(5,6)] ddrIn   :: ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast))-  => Clock slow gated+     , NFDataX a+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )+  => Clock slow   -- ^ clock-  -> Reset slow synchronous+  -> Reset slow   -- ^ reset+  -> Enable slow   -> (a, a, a)   -- ^ reset values   -> Signal fast a   -- ^ DDR input signal-  -> Signal slow (a,a)+  -> Signal slow (a, a)   -- ^ normal speed output pairs-ddrIn clk rst (i0,i1,i2) = withFrozenCallStack $ ddrIn# clk rst i0 i1 i2+ddrIn clk rst en (i0,i1,i2) =+  withFrozenCallStack $ ddrIn# clk rst en i0 i1 i2   -- For details about all the seq's en seqX's -- see the [Note: register strictness annotations] in Clash.Signal.Internal ddrIn#-  :: forall a slow fast n pFast gated synchronous+  :: forall a slow fast fPeriod polarity edge reset init    . ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast))-  => Clock slow gated-  -> Reset slow synchronous+     , NFDataX a+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )+  => Clock slow+  -> Reset slow+  -> Enable slow   -> a   -> a   -> a   -> Signal fast a   -> Signal slow (a,a)-ddrIn# (Clock {}) (Sync rst) i0 i1 i2 =-  go ((errorX "ddrIn: initial value 0 undefined")-     ,(errorX "ddrIn: initial value 1 undefined")-     ,(errorX "ddrIn: initial value 2 undefined"))-     rst-  where-    go :: (a,a,a) -> Signal slow Bool -> Signal fast a -> Signal slow (a,a)-    go (o0,o1,o2) rt@(~(r :- rs)) as@(~(x0 :- x1 :- xs)) =-      let (o0',o1',o2') = if r then (i0,i1,i2) else (o2,x0,x1)-      in o0 `seqX` o1 `seqX` (o0,o1) :- (rt `seq` as `seq` go (o0',o1',o2') rs xs)--ddrIn# (Clock {}) (Async rst) i0 i1 i2 =-  go ((errorX "ddrIn: initial value 0 undefined")-     ,(errorX "ddrIn: initial value 1 undefined")-     ,(errorX "ddrIn: initial value 2 undefined"))-     rst-  where-    go :: (a,a,a) -> Signal slow Bool -> Signal fast a -> Signal slow (a,a)-    go (o0,o1,o2) ~(r :- rs) as@(~(x0 :- x1 :- xs)) =-      let (o0',o1',o2') = if r then (i0,i1,i2) else (o0,o1,o2)-      in o0' `seqX` o1' `seqX`(o0',o1') :- (as `seq` go (o2',x0,x1) rs xs)--ddrIn# (GatedClock _ _ ena) (Sync rst) i0 i1 i2 =-  go ((errorX "ddrIn: initial value 0 undefined")-     ,(errorX "ddrIn: initial value 1 undefined")-     ,(errorX "ddrIn: initial value 2 undefined"))-     rst-     ena+ddrIn# (Clock _) (unsafeToHighPolarity -> hRst) (fromEnable -> ena) i0 i1 i2 =+  case resetKind @fast of+    SAsynchronous ->+      goAsync+        ( deepErrorX "ddrIn: initial value 0 undefined"+        , deepErrorX "ddrIn: initial value 1 undefined"+        , deepErrorX "ddrIn: initial value 2 undefined" )+        hRst+        ena+    SSynchronous ->+      goSync+        ( deepErrorX "ddrIn: initial value 0 undefined"+        , deepErrorX "ddrIn: initial value 1 undefined"+        , deepErrorX "ddrIn: initial value 2 undefined" )+        hRst+        ena   where-    go :: (a,a,a) -> Signal slow Bool -> Signal slow Bool -> Signal fast a -> Signal slow (a,a)-    go (o0,o1,o2) rt@(~(r :- rs)) ~(e :- es) as@(~(x0 :- x1 :- xs)) =+    goSync+      :: (a, a, a)+      -> Signal slow Bool+      -> Signal slow Bool+      -> Signal fast a+      -> Signal slow (a,a)+    goSync (o0,o1,o2) rt@(~(r :- rs)) ~(e :- es) as@(~(x0 :- x1 :- xs)) =       let (o0',o1',o2') = if r then (i0,i1,i2) else (o2,x0,x1)       in o0 `seqX` o1 `seqX` (o0,o1)-           :- (rt `seq` as `seq` if e then go (o0',o1',o2') rs es xs-                                      else go (o0 ,o1 ,o2)    rs es xs)+           :- (rt `seq` as `seq` if e then goSync (o0',o1',o2') rs es xs+                                      else goSync (o0 ,o1 ,o2)  rs es xs) -ddrIn# (GatedClock _ _ ena) (Async rst) i0 i1 i2 =-  go ((errorX "ddrIn: initial value 0 undefined")-     ,(errorX "ddrIn: initial value 1 undefined")-     ,(errorX "ddrIn: initial value 2 undefined"))-     rst-     ena-  where-    go :: (a,a,a) -> Signal slow Bool -> Signal slow Bool -> Signal fast a -> Signal slow (a,a)-    go (o0,o1,o2) ~(r :- rs) ~(e :- es) as@(~(x0 :- x1 :- xs)) =-      let (o0',o1',o2') = if r then (i0,i1,i2) else (o0,o1,o2)+    goAsync+      :: (a, a, a)+      -> Signal slow Bool+      -> Signal slow Bool+      -> Signal fast a+      -> Signal slow (a, a)+    goAsync (o0,o1,o2) ~(r :- rs) ~(e :- es) as@(~(x0 :- x1 :- xs)) =+      let (o0',o1',o2',o3',o4') = if r then (i0,i1,i0,i1,i2) else (o0,o1,o2,x0,x1)       in o0' `seqX` o1' `seqX` (o0',o1')-           :- (as `seq` if e then go (o2',x0 ,x1)   rs es xs-                             else go (o0',o1',o2') rs es xs)+           :- (as `seq` if e then goAsync (o2',o3',o4') rs es xs+                             else goAsync (o0',o1',o2') rs es xs)+ {-# NOINLINE ddrIn# #-}+{-# ANN ddrIn# hasBlackBox #-}  -- | DDR output primitive -- -- Produces a DDR output signal from a normal signal of pairs of input.-ddrOut :: ( HasCallStack-          , fast ~ 'Dom n pFast-          , slow ~ 'Dom n (2*pFast))-       => Clock slow gated            -- ^ clock-       -> Reset slow synchronous      -- ^ reset-       -> a                           -- ^ reset value-       -> Signal slow (a,a)           -- ^ normal speed input pairs-       -> Signal fast a               -- ^ DDR output signal-ddrOut clk rst i0 = uncurry (withFrozenCallStack $ ddrOut# clk rst i0) . unbundle+--+-- >>> sampleN 7 $ ddrOut systemClockGen asyncResetGen (-1) (fromList [(0,1),(2,3),(4,5)])+-- [-1,-1,-1,2,3,4,5]+ddrOut+  :: ( HasCallStack+     , NFDataX a+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )+  => Clock slow+  -> Reset slow+  -> Enable slow+  -> a+  -- ^ reset value+  -> Signal slow (a, a)+  -- ^ Normal speed input pairs+  -> Signal fast a+  -- ^ DDR output signal+ddrOut clk rst en i0 =+  uncurry (withFrozenCallStack $ ddrOut# clk rst en i0) . unbundle  -ddrOut# :: ( HasCallStack-           , fast ~ 'Dom n pFast-           , slow ~ 'Dom n (2*pFast))-        => Clock slow gated-        -> Reset slow synchronous-        -> a-        -> Signal slow a-        -> Signal slow a-        -> Signal fast a-ddrOut# clk rst i0 xs ys =+ddrOut#+  :: ( HasCallStack+     , NFDataX a+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )+  => Clock slow+  -> Reset slow+  -> Enable slow+  -> a+  -> Signal slow a+  -> Signal slow a+  -> Signal fast a+ddrOut# clk rst en i0 xs ys =     -- We only observe one reset value, because when the mux switches on the     -- next clock level, the second register will already be outputting its     -- first input.@@ -155,7 +178,8 @@     -- That is why we drop the first value of the stream.     let (_ :- out) = zipSig xs' ys' in out   where-    xs' = register clk rst i0 xs-    ys' = register clk rst i0 ys+    xs' = register# clk rst en (error "ddrOut: unreachable error") i0 xs+    ys' = register# clk rst en (deepErrorX "ddrOut: initial value undefined") i0 ys     zipSig (a :- as) (b :- bs) = a :- b :- zipSig as bs {-# NOINLINE ddrOut# #-}+{-# ANN ddrOut# hasBlackBox #-}
src/Clash/Explicit/Mealy.hs view
@@ -1,6 +1,7 @@ {-|   Copyright  :  (C) 2013-2016, University of Twente,                     2017     , Google Inc.+                    2019     , Myrtle Software Ltd   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -20,7 +21,9 @@   ) where -import Clash.Explicit.Signal (Bundle (..), Clock, Reset, Signal, register)+import           Clash.Explicit.Signal+  (KnownDomain, Bundle (..), Clock, Reset, Signal, Enable, register)+import           Clash.XException      (NFDataX)  {- $setup >>> :set -XDataKinds -XTypeApplications@@ -32,7 +35,7 @@         s' = x * y + s :} ->>> let mac clk rst = mealy clk rst macT 0+>>> let mac clk rst en = mealy clk rst en macT 0 -}  -- | Create a synchronous function from a combinational function describing@@ -50,15 +53,17 @@ --     s' = x * y + s -- -- mac---   :: 'Clock' domain Source---   -> 'Reset' domain Asynchronous---   -> 'Signal' domain (Int, Int)---   -> 'Signal' domain Int--- mac clk rst = 'mealy' clk rst macT 0+--   :: 'KnownDomain' dom+--   => 'Clock' dom+--   -> 'Reset' dom+--   -> 'Enable' dom+--   -> 'Signal' dom (Int, Int)+--   -> 'Signal' dom Int+-- mac clk rst en = 'mealy' clk rst en macT 0 -- @ ----- >>> simulate (mac systemClockGen systemResetGen) [(1,1),(2,2),(3,3),(4,4)]--- [0,1,5,14...+-- >>> simulate (mac systemClockGen systemResetGen enableGen) [(0,0),(1,1),(2,2),(3,3),(4,4)]+-- [0,0,1,5,14... -- ... -- -- Synchronous sequential functions can be composed just like their@@ -66,26 +71,36 @@ -- -- @ -- dualMac---   :: 'Clock' domain gated -> 'Reset' domain synchronous---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> 'Signal' domain Int--- dualMac clk rst (a,b) (x,y) = s1 + s2+--   :: 'KnownDomain' dom+--   => 'Clock' dom+--   -> 'Reset' dom+--   -> 'Enable' dom+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> 'Signal' dom Int+-- dualMac clk rst en (a,b) (x,y) = s1 + s2 --   where---     s1 = 'mealy' clk rst mac 0 ('bundle' (a,x))---     s2 = 'mealy' clk rst mac 0 ('bundle' (b,y))+--     s1 = 'mealy' clk rst en mac 0 ('bundle' (a,x))+--     s2 = 'mealy' clk rst en mac 0 ('bundle' (b,y)) -- @-mealy :: Clock dom gated   -- ^ 'Clock' to synchronize to-      -> Reset dom synchronous-      -> (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:-                           -- @state -> input -> (newstate,output)@-      -> s                 -- ^ Initial state-      -> (Signal dom i -> Signal dom o)-      -- ^ Synchronous sequential function with input and output matching that-      -- of the mealy machine-mealy clk rst f iS =+mealy+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Reset dom+  -> Enable dom+  -- ^ Global enable+  -> (s -> i -> (s,o))+  -- ^ Transfer function in mealy machine form: @state -> input -> (newstate,output)@+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealy clk rst en f iS =   \i -> let (s',o) = unbundle $ f <$> s <*> i-            s      = register clk rst iS s'+            s      = register clk rst en iS s'         in  o {-# INLINABLE mealy #-} @@ -97,32 +112,38 @@ -- __f__ :: Int -> (Bool,Int) -> (Int,(Int,Bool)) -- @ ----- When we want to make compositions of @f@ in @g@ using 'mealy'', we have to+-- When we want to make compositions of @f@ in @g@ using 'mealy', we have to -- write: -- -- @--- g clk rst a b c = (b1,b2,i2)+-- g clk rst en a b c = (b1,b2,i2) --   where---     (i1,b1) = 'unbundle' (mealy clk rst f 0 ('bundle' (a,b)))---     (i2,b2) = 'unbundle' (mealy clk rst f 3 ('bundle' (i1,c)))+--     (i1,b1) = 'unbundle' (mealy clk rst en f 0 ('bundle' (a,b)))+--     (i2,b2) = 'unbundle' (mealy clk rst en f 3 ('bundle' (c,i1))) -- @ ----- Using 'mealyB'' however we can write:+-- Using 'mealyB' however we can write: -- -- @--- g clk rst a b c = (b1,b2,i2)+-- g clk rst en a b c = (b1,b2,i2) --   where---     (i1,b1) = 'mealyB' clk rst f 0 (a,b)---     (i2,b2) = 'mealyB' clk rst f 3 (i1,c)+--     (i1,b1) = 'mealyB' clk rst en f 0 (a,b)+--     (i2,b2) = 'mealyB' clk rst en f 3 (c,i1) -- @-mealyB :: (Bundle i, Bundle o)-       => Clock dom gated-       -> Reset dom synchronous-       -> (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:-                    -- @state -> input -> (newstate,output)@-       -> s                 -- ^ Initial state-       -> (Unbundled dom i -> Unbundled dom o)-       -- ^ Synchronous sequential function with input and output matching that-       -- of the mealy machine-mealyB clk rst f iS i = unbundle (mealy clk rst f iS (bundle i))+mealyB+  :: ( KnownDomain dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (s -> i -> (s,o))+  -- ^ Transfer function in mealy machine form: @state -> input -> (newstate,output)@+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)+ -- ^ Synchronous sequential function with input and output matching that+ -- of the mealy machine+mealyB clk rst en f iS i = unbundle (mealy clk rst en f iS (bundle i)) {-# INLINE mealyB #-}
src/Clash/Explicit/Moore.hs view
@@ -1,6 +1,7 @@ {-|   Copyright  :  (C) 2013-2016, University of Twente,                     2017     , Google Inc.+                    2019     , Myrtle Software Ltd   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -22,13 +23,15 @@   ) where -import Clash.Explicit.Signal (Bundle (..), Clock, Reset, Signal, register)+import           Clash.Explicit.Signal+  (KnownDomain, Bundle (..), Clock, Reset, Signal, Enable, register)+import           Clash.XException                 (NFDataX)  {- $setup >>> :set -XDataKinds -XTypeApplications >>> import Clash.Explicit.Prelude >>> let macT s (x,y) = x * y + s->>> let mac clk rst = moore clk rst macT id 0+>>> let mac clk rst en = moore clk rst en macT id 0 -}  -- | Create a synchronous function from a combinational function describing@@ -42,15 +45,17 @@ -- macT s (x,y) = x * y + s -- -- mac---   :: 'Clock' mac Source---   -> 'Reset' mac Asynchronous---   -> 'Signal' mac (Int, Int)---   -> 'Signal' mac Int--- mac clk rst = 'moore' clk rst macT id 0+--   :: 'KnownDomain' dom+--   => 'Clock' dom+--   -> 'Reset' dom+--   -> 'Enable' dom+--   -> 'Signal' dom (Int, Int)+--   -> 'Signal' dom Int+-- mac clk rst en = 'moore' clk rst en macT id 0 -- @ ----- >>> simulate (mac systemClockGen systemResetGen) [(1,1),(2,2),(3,3),(4,4)]--- [0,1,5,14...+-- >>> simulate (mac systemClockGen systemResetGen enableGen) [(0,0),(1,1),(2,2),(3,3),(4,4)]+-- [0,0,1,5,14... -- ... -- -- Synchronous sequential functions can be composed just like their@@ -58,42 +63,52 @@ -- -- @ -- dualMac---   :: Clock domain gated---   -> Reset domain synchronous---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> 'Signal' domain Int--- dualMac clk rst (a,b) (x,y) = s1 + s2+--   :: 'KnownDomain' dom+--   => 'Clock' dom+--   -> 'Reset' dom+--   -> 'Enable' dom+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> 'Signal' dom Int+-- dualMac clk rst en (a,b) (x,y) = s1 + s2 --   where---     s1 = 'moore' clk rst mac id 0 ('bundle' (a,x))---     s2 = 'moore' clk rst mac id 0 ('bundle' (b,y))+--     s1 = 'moore' clk rst en mac id 0 ('bundle' (a,x))+--     s2 = 'moore' clk rst en mac id 0 ('bundle' (b,y)) -- @ moore-  :: Clock domain gated       -- ^ 'Clock' to synchronize to-  -> Reset domain synchronous-  -> (s -> i -> s)         -- ^ Transfer function in moore machine form:-                           -- @state -> input -> newstate@-  -> (s -> o)              -- ^ Output function in moore machine form:-                           -- @state -> output@-  -> s                     -- ^ Initial state-  -> (Signal domain i -> Signal domain o)+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Reset dom+  -> Enable dom+  -> (s -> i -> s)+  -- ^ Transfer function in moore machine form: @state -> input -> newstate@+  -> (s -> o)+  -- ^ Output function in moore machine form: @state -> output@+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)   -- ^ Synchronous sequential function with input and output matching that   -- of the moore machine-moore clk rst ft fo iS =+moore clk rst en ft fo iS =   \i -> let s' = ft <$> s <*> i-            s  = register clk rst iS s'+            s  = register clk rst en iS s'         in fo <$> s {-# INLINABLE moore #-}  -- | Create a synchronous function from a combinational function describing -- a moore machine without any output logic medvedev-  :: Clock domain gated-  -> Reset domain synchronous+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> (s -> i -> s)   -> s-  -> (Signal domain i -> Signal domain s)-medvedev clk rst tr st = moore clk rst tr id st+  -> (Signal dom i -> Signal dom s)+medvedev clk rst en tr st = moore clk rst en tr id st {-# INLINE medvedev #-}  -- | A version of 'moore' that does automatic 'Bundle'ing@@ -105,46 +120,57 @@ -- __o__ :: Int -> (Int, Bool) -- @ ----- When we want to make compositions of @t@ and @o@ in @g@ using 'moore'', we have to+-- When we want to make compositions of @t@ and @o@ in @g@ using 'moore', we have to -- write: -- -- @--- g clk rst a b c = (b1,b2,i2)+-- g clk rst en a b c = (b1,b2,i2) --   where---     (i1,b1) = 'unbundle' (moore clk rst t o 0 ('bundle' (a,b)))---     (i2,b2) = 'unbundle' (moore clk rst t o 3 ('bundle' (i1,c)))+--     (i1,b1) = 'unbundle' (moore clk rst en t o 0 ('bundle' (a,b)))+--     (i2,b2) = 'unbundle' (moore clk rst en t o 3 ('bundle' (c,i1))) -- @ ----- Using 'mooreB'' however we can write:+-- Using 'mooreB' however we can write: -- -- @--- g clk rst a b c = (b1,b2,i2)+-- g clk rst en a b c = (b1,b2,i2) --   where---     (i1,b1) = 'mooreB' clk rst t o 0 (a,b)---     (i2,b2) = 'mooreB' clk rst t o 3 (i1,c)+--     (i1,b1) = 'mooreB' clk rst en t o 0 (a,b)+--     (i2,b2) = 'mooreB' clk rst en t o 3 (c,i1) -- @ mooreB-  :: (Bundle i, Bundle o)-  => Clock domain gated-  -> Reset domain synchronous-  -> (s -> i -> s) -- ^ Transfer function in moore machine form:-                   -- @state -> input -> newstate@-  -> (s -> o)      -- ^ Output function in moore machine form:-                   -- @state -> output@-  -> s             -- ^ Initial state-  -> (Unbundled domain i -> Unbundled domain o)+  :: ( KnownDomain dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (s -> i -> s)+  -- ^ Transfer function in moore machine form:+  -- @state -> input -> newstate@+  -> (s -> o)+  -- ^ Output function in moore machine form:+  -- @state -> output@+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)   -- ^ Synchronous sequential function with input and output matching that   -- of the moore machine-mooreB clk rst ft fo iS i = unbundle (moore clk rst ft fo iS (bundle i))+mooreB clk rst en ft fo iS i = unbundle (moore clk rst en ft fo iS (bundle i)) {-# INLINE mooreB #-}  -- | A version of 'medvedev' that does automatic 'Bundle'ing medvedevB-  :: (Bundle i, Bundle s)-  => Clock domain gated-  -> Reset domain synchronous+  :: ( KnownDomain dom+     , NFDataX s+     , Bundle i+     , Bundle s )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> (s -> i -> s)   -> s-  -> (Unbundled domain i -> Unbundled domain s)-medvedevB clk rst tr st = mooreB clk rst tr id st+  -> (Unbundled dom i -> Unbundled dom s)+medvedevB clk rst en tr st = mooreB clk rst en tr id st {-# INLINE medvedevB #-}
src/Clash/Explicit/Prelude.hs view
@@ -1,22 +1,22 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  This module defines the explicitly clocked counterparts of the functions-defined in "Clash.Prelude". Take a look at "Clash.Signal.Explicit" to see how-you can make multi-clock designs.+defined in "Clash.Prelude". -} -{-# LANGUAGE DataKinds     #-}+{-# LANGUAGE DataKinds         #-} {-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeOperators     #-}  {-# LANGUAGE Unsafe #-}  {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}-{-# OPTIONS_HADDOCK show-extensions #-}+{-# OPTIONS_HADDOCK show-extensions, not-home #-}  module Clash.Explicit.Prelude   ( -- * Creating synchronous sequential circuits@@ -33,7 +33,7 @@   , asyncRomPow2   , rom   , romPow2-    -- ** ROMs initialised with a data file+    -- ** ROMs initialized with a data file   , asyncRomFile   , asyncRomFilePow2   , romFile@@ -44,7 +44,10 @@     -- * BlockRAM primitives   , blockRam   , blockRamPow2-    -- ** BlockRAM primitives initialised with a data file+  , blockRamU+  , blockRam1+  , ResetStrategy(..)+    -- ** BlockRAM primitives initialized with a data file   , blockRamFile   , blockRamFilePow2   -- ** BlockRAM read/write conflict resolution@@ -57,7 +60,16 @@     -- * Testbench functions   , assert   , stimuliGenerator-  , outputVerifier+  , outputVerifier'+    -- * Tracing+    -- ** Simple+  , traceSignal1+  , traceVecSignal1+    -- ** Tracing in a multi-clock environment+  , traceSignal+  , traceVecSignal+    -- ** VCD dump functions+  , dumpVCD     -- * Exported modules     -- ** Synchronous signals   , module Clash.Explicit.Signal@@ -81,6 +93,9 @@   , module Clash.Sized.RTree     -- ** Annotations   , module Clash.Annotations.TopEntity+    -- ** Generics type-classes+  , Generic+  , Generic1     -- ** Type-level natural numbers   , module GHC.TypeLits   , module GHC.TypeLits.Extra@@ -94,38 +109,40 @@     -- ** Type classes     -- *** Clash   , module Clash.Class.BitPack+  , module Clash.Class.Exp   , module Clash.Class.Num   , module Clash.Class.Resize     -- *** Other   , module Control.Applicative   , module Data.Bits-  , module Data.Default+  , module Data.Default.Class     -- ** Exceptions   , module Clash.XException   , undefined     -- ** Named types   , module Clash.NamedTypes+    -- ** Magic+  , module Clash.Magic     -- ** Haskell Prelude     -- $hiding-  , module Prelude+  , module Clash.HaskellPrelude   ) where  import Control.Applicative import Data.Bits-import Data.Default+import Data.Default.Class import GHC.TypeLits import GHC.TypeLits.Extra import Language.Haskell.TH.Syntax  (Lift(..))-import Prelude hiding-  ((++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate,-   last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt, tail,-   take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined)+import Clash.HaskellPrelude  import Clash.Annotations.TopEntity import Clash.Class.BitPack+import Clash.Class.Exp import Clash.Class.Num import Clash.Class.Resize+import Clash.Magic import Clash.NamedTypes import Clash.Explicit.BlockRam import Clash.Explicit.BlockRam.File@@ -137,18 +154,16 @@ import Clash.Explicit.Prelude.Safe import Clash.Explicit.Signal import Clash.Explicit.Signal.Delayed-import Clash.Explicit.Synchronizer-  (dualFlipFlopSynchronizer, asyncFIFOSynchronizer) import Clash.Explicit.Testbench import Clash.Prelude.BitIndex import Clash.Prelude.BitReduction import Clash.Prelude.DataFlow-import Clash.Prelude.ROM            (asyncRom, asyncRomPow2) import Clash.Prelude.ROM.File       (asyncRomFile, asyncRomFilePow2) import Clash.Promoted.Nat import Clash.Promoted.Nat.TH import Clash.Promoted.Nat.Literals import Clash.Promoted.Symbol+import Clash.Signal.Trace import Clash.Sized.BitVector import Clash.Sized.Fixed import Clash.Sized.Index@@ -169,50 +184,71 @@ -- -- @ -- window4----  :: Clock domain gated -> Reset domain synchronous---   -> 'Signal' domain Int -> 'Vec' 4 ('Signal' domain Int)+---  :: Clock dom+--   -> Reset dom+--   -> Enable dom+--   -> 'Signal' dom Int+--   -> 'Vec' 4 ('Signal' dom Int) -- window4 = 'window' -- @ ----- >>> simulateB (window4 systemClockGen systemResetGen) [1::Int,2,3,4,5] :: [Vec 4 Int]+-- >>> simulateB (window4 systemClockGen systemResetGen enableGen) [1::Int,2,3,4,5] :: [Vec 4 Int] -- [<1,0,0,0>,<2,1,0,0>,<3,2,1,0>,<4,3,2,1>,<5,4,3,2>... -- ... window-  :: (KnownNat n, Default a)-  => Clock domain gated-  -- ^ Clock to which the incoming signal is synchronized-  -> Reset domain synchronous-  -> Signal domain a               -- ^ Signal to create a window over-  -> Vec (n + 1) (Signal domain a) -- ^ Window of at least size 1-window clk rst x = res+  :: ( KnownNat n+     , KnownDomain dom+     , NFDataX a+     , Default a+     )+  => Clock dom+  -- ^ Clock to the incoming signal is synchronized+  -> Reset dom+  -> Enable dom+  -> Signal dom a+  -- ^ Signal to create a window over+  -> Vec (n + 1) (Signal dom a)+  -- ^ Window of at least size 1+window clk rst en x = res   where     res  = x :> prev     prev = case natVal (asNatProxy prev) of              0 -> repeat def              _ -> let next = x +>> prev-                  in  registerB clk rst (repeat def) next+                  in  registerB clk rst en (repeat def) next {-# INLINABLE window #-}  -- | Give a delayed window over a 'Signal' -- -- @--- windowD3 :: Clock domain gated -> Reset domain synchronous---          -> 'Signal' domain Int -> 'Vec' 3 ('Signal' domain Int)+-- windowD3+--   :: KnownDomain dom+--   -> Clock dom+--   -> Enable dom+--   -> Reset dom+--   -> 'Signal' dom Int+--   -> 'Vec' 3 ('Signal' dom Int) -- windowD3 = 'windowD' -- @ ----- >>> simulateB (windowD3 systemClockGen systemResetGen) [1::Int,2,3,4] :: [Vec 3 Int]--- [<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>...+-- >>> simulateB (windowD3 systemClockGen resetGen enableGen) [1::Int,1,2,3,4] :: [Vec 3 Int]+-- [<0,0,0>,<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>... -- ... windowD-  :: (KnownNat n, Default a)-  => Clock domain gated+  :: ( KnownNat n+     , NFDataX a+     , Default a+     , KnownDomain dom )+  => Clock dom   -- ^ Clock to which the incoming signal is synchronized-  -> Reset domain synchronous-  -> Signal domain a                -- ^ Signal to create a window over-  -> Vec (n + 1) (Signal domain a)  -- ^ Window of at least size 1-windowD clk rst x =-  let prev = registerB clk rst (repeat def) next+  -> Reset dom+  -> Enable dom+  -> Signal dom a+  -- ^ Signal to create a window over+  -> Vec (n + 1) (Signal dom a)+  -- ^ Window of at least size 1+windowD clk rst en x =+  let prev = registerB clk rst en (repeat def) next       next = x +>> prev   in  prev {-# INLINABLE windowD #-}
src/Clash/Explicit/Prelude/Safe.hs view
@@ -1,24 +1,25 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -__This is the <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe-haskell.html Safe> API only of "Clash.Explicit.Prelude"__+__This is the <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe_haskell.html Safe> API only of "Clash.Explicit.Prelude"__  This module defines the explicitly clocked counterparts of the functions-defined in "Clash.Prelude". Take a look at "Clash.Signal.Explicit" to see how-you can make multi-clock designs.+defined in "Clash.Prelude". -}  {-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE NoImplicitPrelude   #-} {-# LANGUAGE TypeOperators       #-} {-# LANGUAGE ScopedTypeVariables #-}  {-# LANGUAGE Safe #-} -{-# OPTIONS_HADDOCK show-extensions #-}+{-# OPTIONS_HADDOCK show-extensions, not-home #-}  module Clash.Explicit.Prelude.Safe   ( -- * Creating synchronous sequential circuits@@ -71,6 +72,9 @@   , module Clash.Sized.RTree     -- ** Annotations   , module Clash.Annotations.TopEntity+    -- ** Generics type-classes+  , Generic+  , Generic1     -- ** Type-level natural numbers   , module GHC.TypeLits   , module GHC.TypeLits.Extra@@ -94,19 +98,18 @@   , module Clash.NamedTypes     -- ** Haskell Prelude     -- $hiding-  , module Prelude+  , module Clash.HaskellPrelude   ) where  import Control.Applicative import Data.Bits+import GHC.Generics (Generic, Generic1) import GHC.Stack import GHC.TypeLits import GHC.TypeLits.Extra-import Prelude hiding-  ((++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate,-   last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt, tail,-   take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined)+import Clash.HaskellPrelude+import qualified Prelude  import Clash.Annotations.TopEntity import Clash.Class.BitPack@@ -143,7 +146,7 @@ {- $setup >>> :set -XDataKinds >>> import Clash.Explicit.Prelude->>> let rP clk rst = registerB clk rst (8::Int,8::Int)+>>> let rP clk rst en = registerB clk rst en (8::Int,8::Int) -}  @@ -151,50 +154,62 @@ -- @('Signal' a, 'Signal' b)@) -- -- @--- rP :: Clock domain gated -> Reset domain synchronous---    -> ('Signal' domain Int, 'Signal' domain Int)---    -> ('Signal' domain Int, 'Signal' domain Int)--- rP clk rst = 'registerB' clk rst (8,8)+-- rP :: Clock dom -> Reset dom -> Enable dom+--    -> ('Signal' dom Int, 'Signal' dom Int)+--    -> ('Signal' dom Int, 'Signal' dom Int)+-- rP clk rst en = 'registerB' clk rst en (8,8) -- @ ----- >>> simulateB (rP systemClockGen systemResetGen) [(1,1),(2,2),(3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...+-- >>> simulateB (rP systemClockGen systemResetGen enableGen) [(1,1),(1,1),(2,2),(3,3)] :: [(Int,Int)]+-- [(8,8),(8,8),(1,1),(2,2),(3,3)... -- ... registerB-  :: Bundle a-  => Clock domain gated-  -> Reset domain synchronous+  :: ( KnownDomain dom+     , NFDataX a+     , Bundle a )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> a-  -> Unbundled domain a-  -> Unbundled domain a-registerB clk rst i = unbundle Prelude.. register clk rst i Prelude.. bundle+  -> Unbundled dom a+  -> Unbundled dom a+registerB clk rst en i =+  unbundle Prelude.. register clk rst en i Prelude.. bundle {-# INLINE registerB #-}  -- | Give a pulse when the 'Signal' goes from 'minBound' to 'maxBound' isRising-  :: (Bounded a, Eq a)-  => Clock domain gated-  -> Reset domain synchronous+  :: ( KnownDomain dom+     , NFDataX a+     , Bounded a+     , Eq a )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> a -- ^ Starting value-  -> Signal domain a-  -> Signal domain Bool-isRising clk rst is s = liftA2 edgeDetect prev s+  -> Signal dom a+  -> Signal dom Bool+isRising clk rst en is s = liftA2 edgeDetect prev s   where-    prev = register clk rst is s+    prev = register clk rst en is s     edgeDetect old new = old == minBound && new == maxBound {-# INLINABLE isRising #-}  -- | Give a pulse when the 'Signal' goes from 'maxBound' to 'minBound' isFalling-  :: (Bounded a, Eq a)-  => Clock domain gated-  -> Reset domain synchronous+  :: ( KnownDomain dom+     , NFDataX a+     , Bounded a+     , Eq a )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> a -- ^ Starting value-  -> Signal domain a-  -> Signal domain Bool-isFalling clk rst is s = liftA2 edgeDetect prev s+  -> Signal dom a+  -> Signal dom Bool+isFalling clk rst en is s = liftA2 edgeDetect prev s   where-    prev = register clk rst is s+    prev = register clk rst en is s     edgeDetect old new = old == maxBound && new == minBound {-# INLINABLE isFalling #-} @@ -202,12 +217,14 @@ -- combined with functions like @'Clash.Explicit.Signal.regEn'@ or -- @'Clash.Explicit.Signal.mux'@, in order to delay a register by a known amount. riseEvery-  :: forall domain gated synchronous n-   . Clock domain gated-  -> Reset domain synchronous+  :: forall dom  n+   . KnownDomain dom+  => Clock dom+  -> Reset dom+  -> Enable dom   -> SNat n-  -> Signal domain Bool-riseEvery clk rst SNat = moore clk rst transfer output 0 (pure ())+  -> Signal dom Bool+riseEvery clk rst en SNat = moore clk rst en transfer output 0 (pure ())   where     output :: Index n -> Bool     output = (== maxBound)@@ -218,19 +235,22 @@  -- | Oscillate a @'Bool'@ for a given number of cycles, given the starting state. oscillate-  :: forall domain gated synchronous n-   . Clock domain gated-  -> Reset domain synchronous+  :: forall dom  n+   . KnownDomain dom+  => Clock dom+  -> Reset dom+  -> Enable dom   -> Bool   -> SNat n-  -> Signal domain Bool-oscillate clk rst begin SNat = moore clk rst transfer snd (0, begin) (pure ())-  where-    transfer :: (Index n, Bool) -> () -> (Index n, Bool)-    transfer (s, i) _ =-      if s == maxBound-        then (0,   not i) -- reset state and oscillate output-        else (s+1, i)     -- hold current output+  -> Signal dom Bool+oscillate clk rst en begin SNat =+  moore clk rst en transfer snd (0, begin) (pure ())+ where+  transfer :: (Index n, Bool) -> () -> (Index n, Bool)+  transfer (s, i) _ =+    if s == maxBound+      then (0,   not i) -- reset state and oscillate output+      else (s+1, i)     -- hold current output {-# INLINEABLE oscillate #-}  undefined :: HasCallStack => a
src/Clash/Explicit/RAM.hs view
@@ -1,6 +1,7 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -26,7 +27,7 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Explicit.RAM-  ( -- * RAM synchronised to an arbitrary clock+  ( -- * RAM synchronized to an arbitrary clock     asyncRam   , asyncRamPow2     -- * Internal@@ -39,11 +40,12 @@ import GHC.TypeLits          (KnownNat) import qualified Data.Vector as V -import Clash.Explicit.Signal ((.&&.), unbundle, unsafeSynchronizer)+import Clash.Explicit.Signal+  (unbundle, unsafeSynchronizer, KnownDomain, enable) import Clash.Promoted.Nat    (SNat (..), snatToNum, pow2SNat)-import Clash.Signal.Internal (Clock (..), Signal (..), clockEnable)+import Clash.Signal.Internal (Clock (..), Signal (..), Enable, fromEnable) import Clash.Sized.Unsigned  (Unsigned)-import Clash.XException      (errorX, maybeX)+import Clash.XException      (errorX, maybeIsX)  -- | Create a RAM with space for 2^@n@ elements --@@ -54,20 +56,26 @@ -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- RAM. asyncRamPow2-  :: forall wdom rdom wgated rgated n a-   . (KnownNat n, HasCallStack)-  => Clock wdom wgated-  -- ^ 'Clock' to which to synchronise the write port of the RAM-  -> Clock rdom rgated-  -- ^ 'Clock' to which the read address signal, @r@, is synchronised+  :: forall wdom rdom n a+   . ( KnownNat n+     , HasCallStack+     , KnownDomain wdom+     , KnownDomain rdom+     )+  => Clock wdom+  -- ^ 'Clock' to which to synchronize the write port of the RAM+  -> Clock rdom+  -- ^ 'Clock' to which the read address signal, @r@, is synchronized+  -> Enable wdom+  -- ^ Global enable   -> Signal rdom (Unsigned n)   -- ^ Read address @r@   -> Signal wdom (Maybe (Unsigned n, a))   -- ^ (write address @w@, value to write)   -> Signal rdom a   -- ^ Value of the @RAM@ at address @r@-asyncRamPow2 = \wclk rclk rd wrM -> withFrozenCallStack-  (asyncRam wclk rclk (pow2SNat (SNat @ n)) rd wrM)+asyncRamPow2 = \wclk rclk en rd wrM -> withFrozenCallStack+  (asyncRam wclk rclk en (pow2SNat (SNat @n)) rd wrM) {-# INLINE asyncRamPow2 #-}  @@ -80,11 +88,17 @@ -- * See "Clash.Explicit.BlockRam#usingrams" for more information on how to use a -- RAM. asyncRam-  :: (Enum addr, HasCallStack)-  => Clock wdom wgated-   -- ^ 'Clock' to which to synchronise the write port of the RAM-  -> Clock rdom rgated-   -- ^ 'Clock' to which the read address signal, @r@, is synchronised+  :: ( Enum addr+     , HasCallStack+     , KnownDomain wdom+     , KnownDomain rdom+     )+  => Clock wdom+   -- ^ 'Clock' to which to synchronize the write port of the RAM+  -> Clock rdom+   -- ^ 'Clock' to which the read address signal, @r@, is synchronized to+  -> Enable wdom+  -- ^ Global enable   -> SNat n   -- ^ Size @n@ of the RAM   -> Signal rdom addr@@ -93,36 +107,44 @@   -- ^ (write address @w@, value to write)   -> Signal rdom a    -- ^ Value of the @RAM@ at address @r@-asyncRam = \wclk rclk sz rd wrM ->+asyncRam = \wclk rclk gen sz rd wrM ->   let en       = isJust <$> wrM       (wr,din) = unbundle (fromJust <$> wrM)   in  withFrozenCallStack-      (asyncRam# wclk rclk sz (fromEnum <$> rd) en (fromEnum <$> wr) din)+      (asyncRam# wclk rclk gen sz (fromEnum <$> rd) en (fromEnum <$> wr) din) {-# INLINE asyncRam #-}  -- | RAM primitive asyncRam#-  :: HasCallStack-  => Clock wdom wgated-  -- ^ 'Clock' to which to synchronise the write port of the RAM-  -> Clock rdom rgated-  -- ^ 'Clock' to which the read address signal, @r@, is synchronised-  -> SNat n            -- ^ Size @n@ of the RAM-  -> Signal rdom Int  -- ^ Read address @r@-  -> Signal wdom Bool -- ^ Write enable-  -> Signal wdom Int  -- ^ Write address @w@-  -> Signal wdom a    -- ^ Value to write (at address @w@)-  -> Signal rdom a    -- ^ Value of the @RAM@ at address @r@-asyncRam# wclk rclk sz rd en wr din =+  :: ( HasCallStack+     , KnownDomain wdom+     , KnownDomain rdom )+  => Clock wdom+  -- ^ 'Clock' to which to synchronize the write port of the RAM+  -> Clock rdom+  -- ^ 'Clock' to which the read address signal, @r@, is synchronized+  -> Enable wdom+  -- ^ Global enable+  -> SNat n+  -- ^ Size @n@ of the RAM+  -> Signal rdom Int+  -- ^ Read address @r@+  -> Signal wdom Bool+  -- ^ Write enable+  -> Signal wdom Int+  -- ^ Write address @w@+  -> Signal wdom a+  -- ^ Value to write (at address @w@)+  -> Signal rdom a+  -- ^ Value of the @RAM@ at address @r@+asyncRam# wclk rclk en sz rd we wr din =     unsafeSynchronizer wclk rclk dout   where     rd'  = unsafeSynchronizer rclk wclk rd     ramI = V.replicate               (snatToNum sz)               (withFrozenCallStack (errorX "asyncRam#: initial value undefined"))-    en'  = case clockEnable wclk of-             Nothing  -> en-             Just wgt -> wgt .&&. en+    en' = fromEnable (enable en we)     dout = go ramI rd' en' wr din      go :: V.Vector a -> Signal wdom Int -> Signal wdom Bool@@ -132,11 +154,11 @@           o    = ram V.! r       in  o :- go ram' rs es ws ds -    upd ram we waddr d = case maybeX we of-      Nothing -> case maybeX waddr of+    upd ram we' waddr d = case maybeIsX we' of+      Nothing -> case maybeIsX waddr of         Nothing -> V.map (const (seq waddr d)) ram         Just wa -> ram V.// [(wa,d)]-      Just True -> case maybeX waddr of+      Just True -> case maybeIsX waddr of         Nothing -> V.map (const (seq waddr d)) ram         Just wa -> ram V.// [(wa,d)]       _ -> ram
src/Clash/Explicit/ROM.hs view
@@ -1,23 +1,27 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  ROMs -} -{-# LANGUAGE DataKinds     #-}-{-# LANGUAGE MagicHash     #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE GADTs               #-}+{-# LANGUAGE MagicHash           #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators       #-} -{-# LANGUAGE Safe #-}+{-# LANGUAGE Trustworthy #-}  {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Explicit.ROM-  ( -- * Synchronous ROM synchronised to an arbitrary clock+  ( -- * Synchronous ROM synchronized to an arbitrary clock     rom   , romPow2     -- * Internal@@ -26,18 +30,15 @@ where  import Data.Array             ((!),listArray)+import GHC.Stack              (withFrozenCallStack) import GHC.TypeLits           (KnownNat, type (^)) import Prelude hiding         (length) --- import Clash.Signal           (Signal)--- import Clash.Signal.Explicit  (Signal', SClock, systemClockGen)-import Clash.Explicit.Signal  (Clock, Signal, delay)-+import Clash.Signal.Internal+  (Clock (..), KnownDomain, Signal (..), Enable, fromEnable) import Clash.Sized.Unsigned   (Unsigned)--- import Clash.Signal.Explicit  (register') import Clash.Sized.Vector     (Vec, length, toList)--- import Clash.XException       (errorX)-+import Clash.XException       (deepErrorX, seqX, NFDataX)  -- | A ROM with a synchronous read port, with space for 2^@n@ elements --@@ -49,13 +50,19 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Explicit.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs romPow2-  :: KnownNat n-  => Clock domain gated         -- ^ 'Clock' to synchronize to-  -> Vec (2^n) a                -- ^ ROM content-                                ---                                -- __NB:__ must be a constant-  -> Signal domain (Unsigned n) -- ^ Read address @rd@-  -> Signal domain a            -- ^ The value of the ROM at address @rd@+  :: (KnownDomain dom, KnownNat n, NFDataX a)+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> Vec (2^n) a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Signal dom (Unsigned n)+  -- ^ Read address @rd@+  -> Signal dom a+  -- ^ The value of the ROM at address @rd@ romPow2 = rom {-# INLINE romPow2 #-} @@ -69,29 +76,48 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Explicit.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs rom-  :: (KnownNat n, Enum addr)-  => Clock domain gated -- ^ 'Clock' to synchronize to-  -> Vec n a            -- ^ ROM content-                        ---                        -- __NB:__ must be a constant-  -> Signal domain addr -- ^ Read address @rd@-  -> Signal domain a+  :: (KnownDomain dom, KnownNat n, NFDataX a, Enum addr)+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> Vec n a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Signal dom addr+  -- ^ Read address @rd@+  -> Signal dom a   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-rom = \clk content rd -> rom# clk content (fromEnum <$> rd)+rom = \clk en content rd -> rom# clk en content (fromEnum <$> rd) {-# INLINE rom #-}  -- | ROM primitive rom#-  :: KnownNat n-  => Clock domain gated -- ^ 'Clock' to synchronize to-  -> Vec n a            -- ^ ROM content-                        ---                        -- __NB:__ must be a constant-  -> Signal domain Int  -- ^ Read address @rd@-  -> Signal domain a+  :: forall dom n a+   . (KnownDomain dom, KnownNat n, NFDataX a)+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> Vec n a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Signal dom Int+  -- ^ Read address @rd@+  -> Signal dom a   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-rom# clk content rd = delay clk ((arr !) <$> rd)-  where-    szI = length content-    arr = listArray (0,szI-1) (toList content)+rom# _ en content rd =+  go+    (withFrozenCallStack (deepErrorX "rom: initial value undefined"))+    (fromEnable en)+    ((arr !) <$> rd)+ where+  szI = length content+  arr = listArray (0,szI-1) (toList content)++  go o (e :- es) as@(~(x :- xs)) =+    -- See [Note: register strictness annotations]+    o `seqX` o :- (as `seq` if e then go x es xs else go o es xs) {-# NOINLINE rom# #-}
src/Clash/Explicit/ROM/File.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -= Initialising a ROM with a data file #usingromfiles#+= Initializing a ROM with a data file #usingromfiles# -ROMs initialised with a data file. The BNF grammar for this data file is simple:+ROMs initialized with a data file. The BNF grammar for this data file is simple:  @ FILE = LINE+@@ -34,9 +35,9 @@  @ f-  :: Clock  domain gated-  -> Signal domain (Unsigned 3)-  -> Signal domain (Unsigned 9)+  :: Clock  dom+  -> Signal dom (Unsigned 3)+  -> Signal dom (Unsigned 9) f clk rd = 'Clash.Class.BitPack.unpack' '<$>' 'romFile' clk d7 \"memory.bin\" rd @ @@ -53,9 +54,9 @@  @ g-  :: Clock  domain Source-  -> Signal domain (Unsigned 3)-  -> Signal domain (Unsigned 6,Signed 3)+  :: Clock  dom Regular+  -> Signal dom (Unsigned 3)+  -> Signal dom (Unsigned 6,Signed 3) g clk rd = 'Clash.Class.BitPack.unpack' '<$>' 'romFile' clk d7 \"memory.bin\" rd @ @@ -80,7 +81,7 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Explicit.ROM.File-  ( -- * Synchronous ROM synchronised to an arbitrary clock+  ( -- * Synchronous ROM synchronized to an arbitrary clock     romFile   , romFilePow2     -- * Internal@@ -95,8 +96,9 @@ import Clash.Explicit.BlockRam.File (initMem) import Clash.Promoted.Nat           (SNat (..), pow2SNat, snatToNum) import Clash.Sized.BitVector        (BitVector)-import Clash.Explicit.Signal        (Clock, Signal, delay)+import Clash.Explicit.Signal        (Clock, Enable, Signal, KnownDomain, delay) import Clash.Sized.Unsigned         (Unsigned)+import Clash.XException             (NFDataX(deepErrorX))   -- | A ROM with a synchronous read port, with space for 2^@n@ elements@@ -123,15 +125,20 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. romFilePow2-  :: forall domain gated n m-   . (KnownNat m, KnownNat n)-  => Clock domain gated        -- ^ 'Clock' to synchronize to-  -> FilePath                  -- ^ File describing the content of-                               -- the ROM-  -> Signal domain (Unsigned n)  -- ^ Read address @rd@-  -> Signal domain (BitVector m)+  :: forall dom  n m+   . (KnownNat m, KnownNat n, KnownDomain dom)+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable+  -> FilePath+  -- ^ File describing the content of+  -- the ROM+  -> Signal dom (Unsigned n)+  -- ^ Read address @rd@+  -> Signal dom (BitVector m)   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-romFilePow2 = \clk -> romFile clk (pow2SNat (SNat @ n))+romFilePow2 = \clk en -> romFile clk en (pow2SNat (SNat @ n)) {-# INLINE romFilePow2 #-}  -- | A ROM with a synchronous read port, with space for @n@ elements@@ -158,36 +165,41 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. romFile-  :: (KnownNat m, Enum addr)-  => Clock domain gated+  :: (KnownNat m, Enum addr, KnownDomain dom)+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> SNat n   -- ^ Size of the ROM   -> FilePath   -- ^ File describing the content of the ROM-  -> Signal domain addr+  -> Signal dom addr   -- ^ Read address @rd@-  -> Signal domain (BitVector m)+  -> Signal dom (BitVector m)   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-romFile = \clk sz file rd -> romFile# clk sz file (fromEnum <$> rd)+romFile = \clk en sz file rd -> romFile# clk en sz file (fromEnum <$> rd) {-# INLINE romFile #-}  -- | romFile primitive romFile#-  :: KnownNat m-  => Clock domain gated+  :: (KnownNat m, KnownDomain dom)+  => Clock dom   -- ^ 'Clock' to synchronize to+  -> Enable dom+  -- ^ Global enable   -> SNat n   -- ^ Size of the ROM   -> FilePath   -- ^ File describing the content of the ROM-  -> Signal domain Int+  -> Signal dom Int   -- ^ Read address @rd@-  -> Signal domain (BitVector m)+  -> Signal dom (BitVector m)   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-romFile# clk sz file rd = delay clk ((content !) <$> rd)-  where-    mem     = unsafePerformIO (initMem file)-    content = listArray (0,szI-1) mem-    szI     = snatToNum sz+romFile# clk en sz file rd =+  delay clk en (deepErrorX "First value of romFile is undefined") ((content !) <$> rd)+ where+  mem     = unsafePerformIO (initMem file)+  content = listArray (0,szI-1) mem+  szI     = snatToNum sz {-# NOINLINE romFile# #-}
src/Clash/Explicit/Signal.hs view
@@ -1,66 +1,99 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2016     , Myrtle Software,+                  2016-2019, Myrtle Software,                   2017     , Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -CλaSH has synchronous 'Signal's in the form of:+Clash has synchronous 'Signal's in the form of:  @-'Signal' (domain :: 'Domain') a+'Signal' (dom :: 'GHC.TypeLits.Symbol') a @  Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,-and /domain/ is the /clock-/ (and /reset-/) domain to which the memory elements+and /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements manipulating these 'Signal's belong. -The type-parameter, /domain/, is of the kind 'Domain' which has types of the-following shape:+The type-parameter, /dom/, is of the kind 'Domain' - a simple string. That+string refers to a single /synthesis domain/. A synthesis domain describes the+behavior of certain aspects of memory elements in it. More specifically, a+domain looks like:  @-data Domain = Dom { domainName :: 'GHC.TypeLits.Symbol', clkPeriod :: 'GHC.TypeLits.Nat' }+'DomainConfiguration'+  { _name:: 'GHC.TypeLits.Symbol'+  -- ^ Domain name+  , _period :: 'GHC.TypeLits.Nat'+  -- ^ Clock period in /ps/+  , _edge :: 'ActiveEdge'+  -- ^ Active edge of the clock+  , _reset :: 'ResetKind'+  -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)+  , _init :: 'InitBehavior'+  -- ^ Whether the initial (or "power up") value of memory elements is+  -- unknown/undefined, or configurable to a specific value+  , _polarity :: 'ResetPolarity'+  -- ^ Whether resets are active high or active low+  } @ -Where /domainName/ is a type-level string ('GHC.TypeLits.Symbol') representing-the name of the /clock-/ (and /reset-/) domain, and /clkPeriod/ is a type-level-natural number ('GHC.TypeLits.Nat') representing the clock period (in __ps__)-of the clock lines in the /clock-domain/.+Check the documentation of each of the types to see the various options Clash+provides. In order to specify a domain, an instance of 'KnownDomain' should be+made. Clash provides a standard implementation, called 'System', that is+configured as follows: +@+instance KnownDomain "System" where+  type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = 'SDomainConfiguration' SSymbol SNat 'SRising' 'SAsynchronous' 'SDefined' 'SActiveHigh'+@++In words, \"System\" is a synthesis domain with a clock running with a period+of 10000 /ps/ (100 MHz). Memory elements update their state on the rising edge+of the clock, can be reset asynchronously with regards to the clock, and have+defined power up values if applicable.++In order to create a new domain, you don't have to instantiate it explicitly.+Instead, you can have 'createDomain' create a domain for you. You can also use+the same function to subclass existing domains.+ * __NB__: \"Bad things\"™  happen when you actually use a clock period of @0@, so do __not__ do that! * __NB__: You should be judicious using a clock with period of @1@ as you can never create a clock that goes any faster!+* __NB__: For the best compatibility make sure your period is divisible by 2,+because some VHDL simulators don't support fractions of picoseconds.+* __NB__: Whether 'System' has good defaults depends on your target platform.+Check out 'IntelSystem' and 'XilinxSystem' too!  === Explicit clocks and resets, and meta-stability #metastability# -When <Clash-Signal.html#hiddenclockandreset clocks and resets are implicitly routed>-using the mechanisms provided by the __clash-prelude__, then clocks and resets-are also implicitly unique.--The protection against accidental-<https://en.wikipedia.org/wiki/Metastability_in_electronics metastability>-offered by Clash's /domain/ annotation on 'Signal's is based on the uniqueness-of clocks and resets. But with explicit clock and reset lines, there are-ways to (accidentally) introduce situations that are prone to metastability.+When using multiple clocks and/or reset lines there are ways to accidentally+introduce situations that are prone to+<https://en.wikipedia.org/wiki/Metastability_in_electronics metastability>.+These bugs are incredibly hard to debug as they often cannot be simulated, so+it's best to prevent them in the first place. This section outlines the+situations in which metastability arises and how to prevent it. -There are four different clock and reset lines:+Two types of resets exist: synchronous and asynchronous resets. These reset+types are encoded in a synthesis domain. For the following examples we assume+the following exist:  @-'Reset' domain 'Synchronous'-'Reset' domain 'Asynchronous'-'Clock' domain 'Source'-'Clock' domain 'Gated'+'DomainConfiguration' \"SyncExample\" _period _edge 'Synchronous' _init+'DomainConfiguration' \"AsyncExample\" _period _edge 'Asynchronous' _init @ -We now go over the combinations over these clock and reset line combinations-and explain when they can potentially introduce situations prone to-meta-stability:+See the previous section on how to use domains. +We now go over the clock and reset line combinations and explain when they+can potentially introduce situations prone to meta-stability:+     *   /Reset situation 1/:          @-        f :: Reset domain Synchronous -> Reset domain Synchronous -> ..+        f :: 'Reset' \"SyncExample\" -> 'Reset' \"SyncExample\" -> ..         f x y = ..         @ @@ -71,115 +104,146 @@     *   /Reset situation 2/:          @-        g :: Reset domain Asynchronous -> Reset domain Asynchronous -> ..+        g :: 'Reset' \"AsyncExample\" -> 'Reset' \"AsyncExample\" -> ..         g x y = ..         @          This situation can be prone to metastability, because although /x/ and-        /y/ belong to the same /domain/ according to their type, there is no+        /y/ belong to the same /domain/ according to their domain, there is no         guarantee that they actually originate from the same source. This means         that one component can enter its reset state asynchronously to another         component, inducing metastability in the other component. -        * The Clash compiler will give a warning whenever a function has a-          type-signature similar to the one above.-        * This is the reason why `unsafeFromAsyncReset` is prefixed with the-          word /unsafe/.--    *   /Reset situation 3/:--        @-        h :: Reset domain Asynchronous -> Reset domain Synchronous -> ..-        h x y = ..-        @--        Also this situation is prone to metastability, because again, one-        component can enter its reset state asynchronously to the other,-        inducing metastability in the other component.--          * The Clash compiler will give a warning whenever a function has a-          type-signature similar to the one above.-          * Although in a standalone context, converting between @'Reset' domain-          'Synchronous'@ and @'Signal' domain 'Bool'@ would be safe from a-          metastability point of view, it is not when we're in a context where-          there are also asynchronous resets. That is why 'unsafeToSyncReset'-          is prefixed with the word /unsafe/.--    *   /Clock situations 1, 2, and 3/:+    *   /Clock situation/:          @-        k :: Clock domain Source -> Clock domain source -> ..+        k :: 'Clock' dom -> 'Clock' dom -> ..         k x y = ..--        l :: Clock domain Source -> Clock domain Gated -> ..-        l x y = ..--        m :: Clock domain Gated -> Clock domain Gated -> ..-        m x y = ..         @ -        All the above situations are potentially prone to metastability, because+        The situation above is potentially prone to metastability, because         even though /x/ and /y/ belong to the same /domain/ according to their-        type, there is no guarantee that they actually originate from the same+        domain, there is no guarantee that they actually originate from the same         source. They could hence be connected to completely unrelated clock         sources, and components can then induce metastable states in others. -        * The Clash compiler will give a warning whenever a function has a-        type-signature similar to one of the above three situations. -} -{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs     #-}-{-# LANGUAGE MagicHash #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE ExplicitNamespaces    #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE ViewPatterns          #-}  {-# LANGUAGE Trustworthy #-} +{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}+ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Explicit.Signal   ( -- * Synchronous signal-    Signal, Domain (..), System+    Signal+    -- * Domain+  , Domain+  , KnownDomain(..)+  , KnownConfiguration+  , ActiveEdge(..)+  , SActiveEdge(..)+  , InitBehavior(..)+  , SInitBehavior(..)+  , ResetKind(..)+  , SResetKind(..)+  , ResetPolarity(..)+  , SResetPolarity(..)+  , DomainConfiguration(..)+  , SDomainConfiguration(..)+  -- ** Configuration type families+  , DomainPeriod+  , DomainActiveEdge+  , DomainResetKind+  , DomainInitBehavior+  , DomainResetPolarity+    -- ** Default domains+  , System+  , XilinxSystem+  , IntelSystem+  , vSystem+  , vIntelSystem+  , vXilinxSystem+    -- ** Domain utilities+  , VDomainConfiguration(..)+  , vDomain+  , createDomain+  , knownVDomain+  , clockPeriod+  , activeEdge+  , resetKind+  , initBehavior+  , resetPolarity+    -- ** Enabling+  , Enable(..)+  , toEnable+  , fromEnable+  , enableGen     -- * Clock-  , Clock, ClockKind (..)-  , freqCalc-    -- ** Synchronisation primitive+  , Clock+  , freqCalc  -- DEPRECATED+  , periodToHz+  , hzToPeriod+    -- ** Synchronization primitive   , unsafeSynchronizer-    -- ** Clock gating-  , clockGate+  , veryUnsafeSynchronizer     -- * Reset-  , Reset, ResetKind (..)-  , unsafeFromAsyncReset-  , unsafeToAsyncReset-  , fromSyncReset-  , unsafeToSyncReset+  , Reset(..)+  , unsafeToReset+  , unsafeFromReset+  , unsafeToHighPolarity+  , unsafeToLowPolarity+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+  , convertReset   , resetSynchronizer+  , holdReset     -- * Basic circuit functions+  , enable+  , dflipflop   , delay+  , delayMaybe+  , delayEn   , register   , regMaybe   , regEn     -- * Simulation and testbench functions   , clockGen-  , tbClockGen-  , asyncResetGen-  , syncResetGen+  , resetGen+  , resetGenN   , systemClockGen-  , tbSystemClockGen   , systemResetGen     -- * Boolean connectives   , (.&&.), (.||.)     -- * Product/Signal isomorphism   , Bundle(..)-    -- * Simulation functions (not synthesisable)+    -- * Simulation functions (not synthesizable)   , simulate   , simulateB+  , simulateWithReset+  , simulateWithResetN     -- ** lazy versions   , simulate_lazy   , simulateB_lazy-    -- * List \<-\> Signal conversion (not synthesisable)+    -- * List \<-\> Signal conversion (not synthesizable)   , sample   , sampleN   , fromList+  , fromListWithReset     -- ** lazy versions   , sample_lazy   , sampleN_lazy@@ -194,77 +258,71 @@   ) where -import Control.DeepSeq       (NFData)-import Data.Maybe            (isJust, fromJust)-import GHC.Stack             (HasCallStack, withFrozenCallStack)+import           Data.Maybe                     (isJust, fromJust)+import           GHC.TypeLits                   (type (+), type (<=)) -import Clash.Signal.Internal-import Clash.Signal.Bundle   (Bundle (..))+import           Clash.Annotations.Primitive    (hasBlackBox)+import           Clash.Class.Num                (satSucc, SaturationMode(SatBound))+import           Clash.Promoted.Nat             (SNat(..), snatToNum)+import           Clash.Signal.Bundle            (Bundle (..))+import           Clash.Signal.Internal+import           Clash.Signal.Internal.Ambiguous+  (knownVDomain, clockPeriod, activeEdge, resetKind, initBehavior, resetPolarity)+import           Clash.Sized.Index              (Index)+import           Clash.XException               (NFDataX, deepErrorX)  {- $setup->>> :set -XDataKinds -XTypeApplications+>>> :set -XDataKinds -XTypeApplications -XFlexibleInstances -XMultiParamTypeClasses -XTypeFamilies+>>> :set -fno-warn-deprecations >>> import Clash.Explicit.Prelude+>>> import Clash.Promoted.Nat (SNat(..)) >>> import qualified Data.List as L->>> type Dom2 = Dom "dom" 2->>> type Dom7 = Dom "dom" 7+>>> :{+instance KnownDomain "Dom2" where+  type KnownConf "Dom2" = 'DomainConfiguration "Dom2" 2 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh+:}++>>> :{+instance KnownDomain "Dom7" where+  type KnownConf "Dom7" = 'DomainConfiguration "Dom7" 7 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh+:}++>>> type Dom2 = "Dom2"+>>> type Dom7 = "Dom7" >>> let clk2 = clockGen @Dom2 >>> let clk7 = clockGen @Dom7->>> let oversampling clkA clkB = delay clkB . unsafeSynchronizer clkA clkB . delay clkA->>> let almostId clkA clkB = delay clkB . unsafeSynchronizer clkA clkB . delay clkA . unsafeSynchronizer clkB clkA . delay clkB->>> let oscillate clk rst = let s = register clk rst False (not <$> s) in s->>> let count clk rst = let s = regEn clk rst 0 (oscillate clk rst) (s + 1) in s+>>> let en2 = enableGen @Dom2+>>> let en7 = enableGen @Dom7+>>> let oversampling clkA clkB enA enB dflt = delay clkB enB dflt . unsafeSynchronizer clkA clkB . delay clkA enA dflt+>>> let almostId clkA clkB enA enB dflt = delay clkB enB dflt . unsafeSynchronizer clkA clkB . delay clkA enA dflt . unsafeSynchronizer clkB clkA . delay clkB enB dflt+>>> let oscillate clk rst en = let s = register clk rst en False (not <$> s) in s+>>> let count clk rst en = let s = regEn clk rst en 0 (oscillate clk rst en) (s + 1) in s >>> :{-sometimes1 clk rst = s where-  s = register clk rst Nothing (switch <$> s)+sometimes1 clk rst en = s where+  s = register clk rst en Nothing (switch <$> s)   switch Nothing = Just 1   switch _       = Nothing :}  >>> :{-countSometimes clk rst = s where-  s = regMaybe clk rst 0 (plusM (pure <$> s) (sometimes1 clk rst))+countSometimes clk rst en = s where+  s = regMaybe clk rst en 0 (plusM (pure <$> s) (sometimes1 clk rst en))   plusM = liftA2 (liftA2 (+)) :}  -}  -- **Clock---- | A /clock/ (and /reset/) domain with clocks running at 100 MHz-type System = 'Dom "system" 10000- -- | Clock generator for the 'System' clock domain. -- -- __NB__: should only be used for simulation, and __not__ for the /testBench/ -- function. For the /testBench/ function, used 'tbSystemClockGen' systemClockGen-  :: Clock System 'Source+  :: Clock System systemClockGen = clockGen --- | Clock generator for the 'System' clock domain.------ __NB__: can be used in the /testBench/ function------ === __Example__------ @--- topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)--- topEntity = concat------ testBench :: Signal System Bool--- testBench = done---   where---     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)---     expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)---     done           = exposeClockReset (expectedOutput (topEntity <$> testInput)) clk rst---     clk            = 'tbSystemClockGen' (not <\$\> done)---     rst            = systemResetGen--- @-tbSystemClockGen-  :: Signal System Bool-  -> Clock System 'Source-tbSystemClockGen = tbClockGen- -- | Reset generator for the 'System' clock domain. -- -- __NB__: should only be used for simulation or the \testBench\ function.@@ -279,13 +337,13 @@ -- testBench = done --   where --     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)---     expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)---     done           = exposeClockReset (expectedOutput (topEntity <$> testInput)) clk rst+--     expectedOutput = outputVerifier' ((1:>2:>3:>4:>5:>6:>Nil):>Nil)+--     done           = exposeClockResetEnable (expectedOutput (topEntity <$> testInput)) clk rst --     clk            = tbSystemClockGen (not <\$\> done) --     rst            = 'systemResetGen' -- @-systemResetGen :: Reset System 'Asynchronous-systemResetGen = asyncResetGen+systemResetGen ::Reset System+systemResetGen = resetGen  -- | Normally, asynchronous resets can be both asynchronously asserted and -- de-asserted. Asynchronous de-assertion can induce meta-stability in the@@ -301,33 +359,39 @@ -- to use a proper synchronizer, for example one of the synchronizers in -- "Clash.Explicit.Synchronizer" ----- __NB:__ Assumes the component(s) being reset have an /active-high/ reset port,--- which all components in __clash-prelude__ have.--- -- === __Example__ -- -- @ -- topEntity---   :: Clock  System Source---   -> Reset  System Asynchronous+--   :: Clock  System+--   -> Reset  System --   -> Signal System Bit --   -> Signal System (BitVector 8) -- topEntity clk rst key1 =---     let  (pllOut,pllStable) = altpll (SSymbol @ "altpll50") clk rst---          rstSync            = 'resetSynchronizer' pllOut (unsafeToAsyncReset pllStable)---     in   exposeClockReset leds pllOut rstSync+--     let  (pllOut,pllStable) = altpll (SSymbol @"altpll50") clk rst+--          rstSync            = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)+--     in   exposeClockResetEnable leds pllOut rstSync --   where --     key1R  = isRising 1 key1---     leds   = mealy blinkerT (1,False,0) key1R+--     leds   = mealy blinkerT (1, False, 0) key1R -- @ resetSynchronizer-  :: Clock domain gated-  -> Reset domain 'Asynchronous-  -> Reset domain 'Asynchronous-resetSynchronizer clk rst  =-  let r1 = register clk rst True (pure False)-      r2 = register clk rst True r1-  in  unsafeToAsyncReset r2+  :: forall dom+   . KnownDomain dom+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> Reset dom+resetSynchronizer clk rst en =+  case resetKind @dom of+    SAsynchronous ->+      let isActiveHigh = case resetPolarity @dom of { SActiveHigh -> True; _ -> False }+          r1 = register clk rst en isActiveHigh (pure (not isActiveHigh))+          r2 = register clk rst en isActiveHigh r1+       in unsafeToReset r2+    SSynchronous ->+      -- Reset is already synchronous, nothing to do!+      rst  -- | Calculate the period, in __ps__, given a frequency in __Hz__ --@@ -336,234 +400,401 @@ -- >>> freqCalc 240e6 -- 4167 ----- __NB__: This function is /not/ synthesisable+-- __NB__: This function is /not/ synthesizable freqCalc :: Double -> Integer-freqCalc freq = ceiling ((1.0 / freq) / 1.0e-12)+freqCalc = toInteger . hzToPeriod+{-# DEPRECATED freqCalc "Use 'hzToPeriod' instead." #-} --- ** Synchronisation primitive-{-# NOINLINE unsafeSynchronizer #-}+-- ** Synchronization primitive -- | The 'unsafeSynchronizer' function is a primitive that must be used to--- connect one clock domain to the other, and will be synthesised to a (bundle+-- connect one clock domain to the other, and will be synthesized to a (bundle -- of) wire(s) in the eventual circuit. This function should only be used as--- part of a proper synchronisation component, such as the following dual+-- part of a proper synchronization component, such as the following dual -- flip-flop synchronizer: -- -- @--- dualFlipFlop :: Clock domA gatedA -> Clock domB gatedB---              -> Signal domA Bit -> Signal domB Bit--- dualFlipFlop clkA clkB = 'delay' clkB . 'delay' clkB---                        . 'unsafeSynchronizer' clkA clkB+-- dualFlipFlop+--   :: Clock domA+--   -> Clock domB+--   -> Enable domA+--   -> Enable domB+--   -> Bit+--   -> Signal domA Bit+--   -> Signal domB Bit+-- dualFlipFlop clkA clkB enA enB dflt =+--   'delay' clkB enB dflt . 'delay' clkB enB dflt . 'unsafeSynchronizer' clkA clkB -- @ -- -- The 'unsafeSynchronizer' works in such a way that, given 2 clocks: -- -- @--- type Dom7 = 'Dom' \"dom\" 7+-- createDomain vSystem{vName=\"Dom7\", vPeriod=7} ----- clk7 :: 'Clock' Dom7 Source+-- clk7 :: 'Clock' Dom7 -- clk7 = 'clockGen'+--+-- en7 :: 'Enable' Dom7+-- en7 = 'enableGen' -- @ -- -- and -- -- @--- type Dom2 = 'Dom' \"dom\" 2+-- createDomain vSystem{vName=\"Dom2\", vPeriod=2} ----- clk2 :: 'Clock' Dom2 Source+-- clk2 :: 'Clock' Dom2 -- clk2 = 'clockGen'+--+-- en2 :: 'Enable' Dom2+-- en2 = 'enableGen' -- @ -- -- Oversampling followed by compression is the identity function plus 2 initial -- values: -- -- @--- 'delay' clkB $+-- 'delay' clkB enB dflt $ -- 'unsafeSynchronizer' clkA clkB $--- 'delay' clkA $+-- 'delay' clkA enA dflt $ -- 'unsafeSynchronizer' clkB clkA $--- 'delay' clkB s+-- 'delay' clkB enB s -- -- == ----- X :- X :- s+-- dflt :- dflt :- s -- @ -- -- Something we can easily observe: -- -- @--- oversampling clkA clkB = 'delay' clkB . 'unsafeSynchronizer' clkA clkB---                        . 'delay' clkA--- almostId clkA clkB = 'delay' clkB . 'unsafeSynchronizer' clkA clkB---                    . 'delay' clkA . 'unsafeSynchronizer' clkB clkA---                    . 'delay' clkB+-- oversampling clkA clkB enA enB dflt =+--   'delay' clkB enB dflt+--     . 'unsafeSynchronizer' clkA clkB+--     . 'delay' clkA enA dflt+-- almostId clkA clkB enA enB dflt =+--   'delay' clkB enB dflt+--     . 'unsafeSynchronizer' clkA clkB+--     . 'delay' clkA enA dflt+--     . 'unsafeSynchronizer' clkB clkA+--     . 'delay' clkB enB dflt -- @ ----- >>> printX (sampleN 37 (oversampling clk7 clk2 (fromList [(1::Int)..10])))--- [X,X,1,1,1,2,2,2,2,3,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9,9,10,10,10,10]--- >>> printX (sampleN 12 (almostId clk2 clk7 (fromList [(1::Int)..10])))--- [X,X,1,2,3,4,5,6,7,8,9,10]+-- >>> sampleN 37 (oversampling clk7 clk2 en7 en2 0 (fromList [(1::Int)..10]))+-- [0,0,1,1,1,2,2,2,2,3,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9,9,10,10,10,10]+-- >>> sampleN 12 (almostId clk2 clk7 en2 en7 0 (fromList [(1::Int)..10]))+-- [0,0,1,2,3,4,5,6,7,8,9,10] unsafeSynchronizer-  :: Clock  domain1 gated1 -- ^ 'Clock' of the incoming signal-  -> Clock  domain2 gated2 -- ^ 'Clock' of the outgoing signal-  -> Signal domain1 a-  -> Signal domain2 a-unsafeSynchronizer clk1 clk2 s = s'-  where-    t1    = clockPeriod clk1-    t2    = clockPeriod clk2-    s' | t1 < t2   = compress   t2 t1 s-       | t1 > t2   = oversample t1 t2 s-       | otherwise = same s+  :: forall dom1 dom2 a+   . ( KnownDomain dom1+     , KnownDomain dom2 )+  => Clock dom1+  -- ^ 'Clock' of the incoming signal+  -> Clock dom2+  -- ^ 'Clock' of the outgoing signal+  -> Signal dom1 a+  -> Signal dom2 a+unsafeSynchronizer _clk1 _clk2 =+  veryUnsafeSynchronizer+    (snatToNum (clockPeriod @dom1))+    (snatToNum (clockPeriod @dom2))+{-# INLINE unsafeSynchronizer #-} -same :: Signal domain1 a -> Signal domain2 a-same (s :- ss) = s :- same ss+-- | Same as 'unsafeSynchronizer', but with manually supplied clock periods.+--+-- Note: this unsafeSynchronizer is defined to be consistent with the vhdl and verilog+-- implementations however as only synchronous signals are represented in Clash this+-- cannot be done precisely and can lead to odd behaviour. For example,+-- @+-- sample $ unsafeSynchronizer @Dom2 @Dom7 . unsafeSynchronizer @Dom7 @Dom2 $ fromList [0..10]+-- > [0,4,4,4,7,7,7,7,11,11,11..+-- @+-- is quite different from the identity,+-- @+-- sample $ fromList [0..10]+-- > [0,1,2,3,4,5,6,7,8,9,10..+-- @+-- with values appearing from the "future".+veryUnsafeSynchronizer+  :: Int+  -- ^ Period of clock belonging to 'dom1'+  -> Int+  -- ^ Period of clock belonging to 'dom2'+  -> Signal dom1 a+  -> Signal dom2 a+veryUnsafeSynchronizer t1 t2+  -- this case is just an optimisation for when the periods are the same+  | t1 == t2 = same -oversample :: Int -> Int -> Signal domain1 a -> Signal domain2 a-oversample high low (s :- ss) = s :- oversampleS (reverse (repSchedule high low)) ss+  | otherwise = go 0 -oversampleS :: [Int] -> Signal domain1 a -> Signal domain2 a-oversampleS sched = oversample' sched   where-    oversample' []     s       = oversampleS sched s-    oversample' (d:ds) (s:-ss) = prefixN d s (oversample' ds ss)--    prefixN 0 _ s = s-    prefixN n x s = x :- prefixN (n-1) x s--compress :: Int -> Int -> Signal domain1 a -> Signal domain2 a-compress high low s = compressS (repSchedule high low) s+  same :: Signal dom1 a -> Signal dom2 a+  same (s :- ss) = s :- same ss -compressS :: [Int] -> Signal domain1 a -> Signal domain2 a-compressS sched = compress' sched-  where-    compress' []     s           = compressS sched s-    compress' (d:ds) ss@(s :- _) = s :- compress' ds (dropS d ss)+  go :: Int -> Signal dom1 a -> Signal dom2 a+  go relativeTime (a :- s)+    | relativeTime <= 0 = a :- go (relativeTime + t2) (a :- s)+    | otherwise = go (relativeTime - t1) s+{-# NOINLINE veryUnsafeSynchronizer #-}+{-# ANN veryUnsafeSynchronizer hasBlackBox #-} -    dropS 0 s         = s-    dropS n (_ :- ss) = dropS (n-1) ss+-- * Basic circuit functions -repSchedule :: Int -> Int -> [Int]-repSchedule high low = take low $ repSchedule' low high 1-  where-    repSchedule' cnt th rep-      | cnt < th  = repSchedule' (cnt+low) th (rep + 1)-      | otherwise = rep : repSchedule' (cnt + low) (th + high) 1+-- | Merge enable signal with signal of bools+enable+  :: Enable dom+  -> Signal dom Bool+  -> Enable dom+enable e0 e1 =+  toEnable (fromEnable e0 .&&. e1) --- * Basic circuit functions+-- | Special version of 'delay' that doesn't take enable signals of any kind.+-- Initial value will be undefined.+dflipflop+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom+  -> Signal dom a+  -> Signal dom a+dflipflop clk i =+  delay+    clk+    (toEnable (pure True))+    (deepErrorX "First value of dflipflop undefined")+    i+{-# INLINE dflipflop #-}  -- | \"@'delay' clk s@\" delays the values in 'Signal' /s/ for once cycle, the--- value at time 0 is /undefined/.+-- value at time 0 is /dflt/. ----- >>> printX (sampleN 3 (delay systemClockGen (fromList [1,2,3,4])))--- [X,1,2]+-- >>> sampleN 3 (delay systemClockGen enableGen 0 (fromList [1,2,3,4]))+-- [0,1,2] delay-  :: HasCallStack-  => Clock domain gated+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom   -- ^ Clock-  -> Signal domain a-  -> Signal domain a-delay = \clk i -> withFrozenCallStack (delay# clk i)+  -> Enable dom+  -- ^ Global enable+  -> a+  -- ^ Initial value+  -> Signal dom a+  -> Signal dom a+delay = delay# {-# INLINE delay #-} +-- | Version of 'delay' that only updates when its third argument is a 'Just'+-- value.+--+-- >>> let input = fromList [Just 1, Just 2, Nothing, Nothing, Just 5, Just 6, Just (7::Int)]+-- >>> sampleN 7 (delayMaybe systemClockGen enableGen 0 input)+-- [0,1,2,2,2,5,6]+delayMaybe+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom+  -- ^ Clock+  -> Enable dom+  -- ^ Global enable+  -> a+  -- ^ Initial value+  -> Signal dom (Maybe a)+  -> Signal dom a+delayMaybe clk gen dflt i =+  delayEn clk gen dflt (isJust <$> i) (fromJust <$> i)+{-# INLINE delayMaybe #-}++-- | Version of 'delay' that only updates when its third argument is asserted.+--+-- >>> let input = fromList [1,2,3,4,5,6,7::Int]+-- >>> let enable = fromList [True,True,False,False,True,True,True]+-- >>> sampleN 7 (delayEn systemClockGen enableGen 0 enable input)+-- [0,1,2,2,2,5,6]+delayEn+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom+  -- ^ Clock+  -> Enable dom+  -- ^ Global enable+  -> a+  -- ^ Initial value+  -> Signal dom Bool+  -- ^ Enable+  -> Signal dom a+  -> Signal dom a+delayEn clk gen dflt en i =+  delay clk (enable gen en) dflt i+{-# INLINE delayEn #-}+ -- | \"@'register' clk rst i s@\" delays the values in 'Signal' /s/ for one -- cycle, and sets the value to @i@ the moment the reset becomes 'False'. ----- >>> sampleN 3 (register systemClockGen systemResetGen 8 (fromList [1,2,3,4]))--- [8,1,2]+-- >>> sampleN 5 (register systemClockGen resetGen enableGen 8 (fromList [1,1,2,3,4]))+-- [8,8,1,2,3] register-  :: HasCallStack-  => Clock domain gated+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom   -- ^ clock-  -> Reset domain synchronous-  -- ^ Reset (active-high), 'register' outputs the reset value when the-  -- reset value becomes 'True'+  -> Reset dom+  -- ^ Reset, 'register' outputs the reset value when the reset is active+  -> Enable dom+  -- ^ Global enable   -> a-  -- ^ Reset value-  -> Signal domain a-  -> Signal domain a-register = \clk rst initial i -> withFrozenCallStack-  (register# clk rst initial i)+  -- ^ Reset value. If the domain has initial values enabled, the reset value+  -- will also be the initial value.+  -> Signal dom a+  -> Signal dom a+register clk rst gen initial i =+  register# clk rst gen initial initial i {-# INLINE register #-}  -- | Version of 'register' that only updates its content when its fourth -- argument is a 'Just' value. So given: -- -- @--- sometimes1 clk rst = s where---   s = 'register' clk rst Nothing (switch '<$>' s)+-- sometimes1 clk rst en = s where+--   s = 'register' clk rst en Nothing (switch '<$>' s) -- --   switch Nothing = Just 1 --   switch _       = Nothing ----- countSometimes clk rst = s where---   s     = 'regMaybe' clk rst 0 (plusM ('pure' '<$>' s) (sometimes1 clk rst))+-- countSometimes clk rst en = s where+--   s     = 'regMaybe' clk rst en 0 (plusM ('pure' '<$>' s) (sometimes1 clk rst en)) --   plusM = liftA2 (liftA2 (+)) -- @ -- -- We get: ----- >>> sampleN 8 (sometimes1 systemClockGen systemResetGen)--- [Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]--- >>> sampleN 8 (count systemClockGen systemResetGen)--- [0,0,1,1,2,2,3,3]+-- >>> sampleN 9 (sometimes1 systemClockGen resetGen enableGen)+-- [Nothing,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]+-- >>> sampleN 9 (count systemClockGen resetGen enableGen)+-- [0,0,0,1,1,2,2,3,3] regMaybe-  :: HasCallStack-  => Clock domain gated+  :: ( KnownDomain dom+     , NFDataX a )+  => Clock dom   -- ^ Clock-  -> Reset domain synchronous-  -- ^ Reset (active-high), 'regMaybe' outputs the reset value when the-  -- reset value becomes 'True'+  -> Reset dom+  -- ^ Reset, 'regMaybe' outputs the reset value when the reset value is active+  -> Enable dom+  -- ^ Global enable   -> a-  -- ^ Reset value-  -> Signal domain (Maybe a)-  -> Signal domain a-regMaybe = \clk rst initial iM -> withFrozenCallStack-  (register# (clockGate clk (fmap isJust iM)) rst initial (fmap fromJust iM))+  -- ^ Reset value. If the domain has initial values enabled, the reset value+  -- will also be the initial value.+  -> Signal dom (Maybe a)+  -> Signal dom a+regMaybe clk rst en initial iM =+  register clk rst (enable en (fmap isJust iM)) initial (fmap fromJust iM) {-# INLINE regMaybe #-}  -- | Version of 'register' that only updates its content when its fourth -- argument is asserted. So given: -- -- @--- oscillate clk rst = let s = 'register' clk rst False (not \<$\> s) in s--- count clk rst     = let s = 'regEn clk rst 0 (oscillate clk rst) (s + 1) in s+-- oscillate clk rst en = let s = 'register' clk rst en False (not \<$\> s) in s+-- count clk rst en     = let s = 'regEn clk rst en 0 (oscillate clk rst en) (s + 1) in s -- @ -- -- We get: ----- >>> sampleN 8 (oscillate systemClockGen systemResetGen)--- [False,True,False,True,False,True,False,True]--- >>> sampleN 8 (count systemClockGen systemResetGen)--- [0,0,1,1,2,2,3,3]+-- >>> sampleN 9 (oscillate systemClockGen resetGen enableGen)+-- [False,False,True,False,True,False,True,False,True]+-- >>> sampleN 9 (count systemClockGen resetGen enableGen)+-- [0,0,0,1,1,2,2,3,3] regEn-  :: Clock domain clk+  :: ( KnownDomain dom+     , NFDataX a+     )+  => Clock dom   -- ^ Clock-  -> Reset domain synchronous-  -- ^ Reset (active-high), 'regEn' outputs the reset value when the-  -- reset value becomes 'True'+  -> Reset dom+  -- ^ Reset, 'regEn' outputs the reset value when the reset value is active+  -> Enable dom+  -- ^ Global enable   -> a-  -- ^ Reset value-  -> Signal domain Bool+  -- ^ Reset value. If the domain has initial values enabled, the reset value+  -- will also be the initial value.+  -> Signal dom Bool   -- ^ Enable signal-  -> Signal domain a-  -> Signal domain a-regEn = \clk rst initial en i -> withFrozenCallStack-  (register# (clockGate clk en) rst initial i)+  -> Signal dom a+  -> Signal dom a+regEn clk rst gen initial en i =+  register clk rst (enable gen en) initial i {-# INLINE regEn #-} --- * Product/Signal isomorphism+-- * Simulation functions +-- | Same as 'simulate', but with the reset line asserted for /n/ cycles. Similar+-- to 'simulate', 'simulateWithReset' will drop the output values produced while+-- the reset is asserted. While the reset is asserted, the first value from+-- @[a]@ is fed to the circuit.+simulateWithReset+  :: forall dom a b m+   . ( KnownDomain dom+     , NFDataX a+     , NFDataX b+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> a+  -- ^ Reset value+  -> ( KnownDomain dom+    => Clock dom+    -> Reset dom+    -> Enable dom+    -> Signal dom a+    -> Signal dom b )+  -- ^ Circuit to simulate+  -> [a]+  -> [b]+simulateWithReset m resetVal f as =+  drop (snatToNum m) out+ where+  inp = replicate (snatToNum m) resetVal ++ as+  rst = resetGenN @dom m+  clk = clockGen+  en  = enableGen+  out = simulate (f clk rst en) inp+{-# NOINLINE simulateWithReset #-}++-- | Same as 'simulateWithReset', but only sample the first /Int/ output values.+simulateWithResetN+  :: ( KnownDomain dom+     , NFDataX a+     , NFDataX b+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> a+  -- ^ Reset value+  -> Int+  -- ^ Number of cycles to simulate (excluding cycle spent in reset)+  -> ( KnownDomain dom+    => Clock dom+    -> Reset dom+    -> Enable dom+    -> Signal dom a+    -> Signal dom b )+  -- ^ Circuit to simulate+  -> [a]+  -> [b]+simulateWithResetN nReset resetVal nSamples f as =+  take nSamples (simulateWithReset nReset resetVal f as)+{-# INLINE simulateWithResetN #-}+ -- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of -- samples of type /a/ ----- >>> simulateB (unbundle . register systemClockGen systemResetGen (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...+-- >>> simulateB (unbundle . register systemClockGen resetGen enableGen (8,8) . bundle) [(1,1), (1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(8,8),(1,1),(2,2),(3,3)... -- ... ----- __NB__: This function is not synthesisable+-- __NB__: This function is not synthesizable simulateB-  :: (Bundle a, Bundle b, NFData a, NFData b)-  => (Unbundled domain1 a -> Unbundled domain2 b)+  :: (Bundle a, Bundle b, NFDataX a, NFDataX b)+  => (Unbundled dom1 a -> Unbundled dom2 b)   -- ^ The function we want to simulate   -> [a]   -- ^ Input samples@@ -573,16 +804,97 @@ -- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a -- list of samples of type /a/ ----- >>> simulateB (unbundle . register systemClockGen systemResetGen (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...+-- >>> simulateB (unbundle . register systemClockGen resetGen enableGen (8,8) . bundle) [(1,1), (1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(8,8),(1,1),(2,2),(3,3)... -- ... ----- __NB__: This function is not synthesisable+-- __NB__: This function is not synthesizable simulateB_lazy   :: (Bundle a, Bundle b)-  => (Unbundled domain1 a -> Unbundled domain2 b)+  => (Unbundled dom1 a -> Unbundled dom2 b)   -- ^ The function we want to simulate   -> [a]   -- ^ Input samples   -> [b] simulateB_lazy f = simulate_lazy (bundle . f . unbundle)+++-- | Hold reset for a number of cycles relative to an incoming reset signal.+--+-- Example:+--+-- >>> let sampleWithReset = sampleN 8 . unsafeToHighPolarity+-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (resetGenN (SNat @3)))+-- [True,True,True,True,True,False,False,False]+--+-- 'holdReset' holds the reset for an additional 2 clock cycles for a total+-- of 5 clock cycles where the reset is asserted. 'holdReset' also works on+-- intermediate assertions of the reset signal:+--+-- >>> let rst = fromList [True, False, False, False, True, False, False, False]+-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (unsafeFromHighPolarity rst))+-- [True,True,True,False,True,True,True,False]+--+holdReset+  :: forall dom n+   . KnownDomain dom+  => Clock dom+  -> Enable dom+  -- ^ Global enable+  -> SNat n+  -- ^ Hold for /n/ cycles, counting from the moment the incoming reset+  -- signal becomes deasserted.+  -> Reset dom+  -- ^ Reset to extend+  -> Reset dom+holdReset clk en SNat rst =+  unsafeFromHighPolarity ((/=maxBound) <$> counter)+ where+  counter :: Signal dom (Index (n+1))+  counter = register clk rst en 0 (satSucc SatBound <$> counter)++-- | Like 'fromList', but resets on reset and has a defined reset value.+--+-- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])+-- >>> let res = fromListWithReset @System rst Nothing [Just 'a', Just 'b', Just 'c']+-- >>> sampleN 6 res+-- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']+--+-- __NB__: This function is not synthesizable+fromListWithReset+  :: forall dom a+   . (KnownDomain dom, NFDataX a)+  => Reset dom+  -> a+  -> [a]+  -> Signal dom a+fromListWithReset rst resetValue vals =+  go (unsafeToHighPolarity rst) vals+ where+  go (r :- rs) _ | r = resetValue :- go rs vals+  go (_ :- rs) [] = deepErrorX "fromListWithReset: input ran out" :- go rs []+  go (_ :- rs) (a : as) = a :- go rs as++-- | Convert between different types of reset, adding a synchronizer in case+-- it needs to convert from an asynchronous to a synchronous reset.+convertReset+  :: forall domA domB+   . ( KnownDomain domA+     , KnownDomain domB+     )+  => Clock domA+  -> Clock domB+  -> Reset domA+  -> Reset domB+convertReset clkA clkB (unsafeToHighPolarity -> rstA0) =+  unsafeFromHighPolarity rstA2+ where+  rstA1 = unsafeSynchronizer clkA clkB rstA0+  rstA2 =+    case (resetKind @domA, resetKind @domB) of+      (SSynchronous,  SSynchronous)  -> rstA1+      (SAsynchronous, SAsynchronous) -> rstA1+      (SSynchronous,  SAsynchronous) -> rstA1+      (SAsynchronous, SSynchronous) ->+        delay clkB enableGen True $+          delay clkB enableGen True rstA1
src/Clash/Explicit/Signal/Delayed.hs view
@@ -1,19 +1,15 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}  {-# LANGUAGE CPP                        #-} {-# LANGUAGE DataKinds                  #-}-{-# LANGUAGE DeriveLift                 #-}-{-# LANGUAGE DeriveTraversable          #-} {-# LANGUAGE GADTs                      #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE KindSignatures             #-}-{-# LANGUAGE MagicHash                  #-} {-# LANGUAGE ScopedTypeVariables        #-} {-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE TypeOperators              #-}@@ -24,15 +20,15 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Explicit.Signal.Delayed-  ( -- * Delay-annotated synchronous signals-    DSignal+  ( DSignal+    -- * Delay-annotated synchronous signals   , delayed   , delayedI   , feedback     -- * Signal \<-\> DSignal conversion   , fromSignal   , toSignal-    -- * List \<-\> DSignal conversion (not synthesisable)+    -- * List \<-\> DSignal conversion (not synthesizable)   , dfromList     -- ** lazy versions   , dfromList_lazy@@ -42,168 +38,117 @@   ) where -import Control.DeepSeq            (NFData) import Data.Coerce                (coerce)-import Data.Default               (Default(..))-import GHC.TypeLits               (KnownNat, Nat, type (+))-import Language.Haskell.TH.Syntax (Lift)+import GHC.TypeLits               (KnownNat, type (+)) import Prelude                    hiding (head, length, repeat)-import Test.QuickCheck            (Arbitrary, CoArbitrary) -import Clash.Promoted.Nat         (SNat) import Clash.Sized.Vector   (Vec, head, length, repeat, shiftInAt0, singleton)+import Clash.Signal.Delayed.Internal+  (DSignal(..), dfromList, dfromList_lazy, fromSignal, toSignal,+   unsafeFromSignal, antiDelay, feedback)+ import Clash.Explicit.Signal-  (Clock, Domain, Reset, Signal, register, fromList, fromList_lazy, bundle,-   unbundle)+  (KnownDomain, Clock, Reset, Signal, Enable, register,  bundle, unbundle) +import Clash.XException           (NFDataX)+ {- $setup >>> :set -XDataKinds >>> :set -XTypeOperators >>> import Clash.Explicit.Prelude->>> let delay3 clk rst = delayed clk rst (0 :> 0 :> 0 :> Nil)->>> let delay2 clk rst = (delayedI clk rst :: DSignal System n Int -> DSignal System (n + 2) Int)+>>> let delay3 clk rst en = delayed clk rst en (-1 :> -1 :> -1 :> Nil)+>>> let delay2 clk rst en = (delayedI clk rst en :: Int -> DSignal System n Int -> DSignal System (n + 2) Int) >>> :{-let mac :: Clock System gated-        -> Reset System synchronous+let mac :: Clock System+        -> Reset System+        -> Enable System         -> DSignal System 0 Int -> DSignal System 0 Int         -> DSignal System 0 Int-    mac clk rst x y = feedback (mac' x y)+    mac clk rst en x y = feedback (mac' x y)       where         mac' :: DSignal System 0 Int -> DSignal System 0 Int              -> DSignal System 0 Int              -> (DSignal System 0 Int, DSignal System 1 Int)         mac' a b acc = let acc' = a * b + acc-                       in  (acc, delayed clk rst (singleton 0) acc')+                       in  (acc, delayed clk rst en (singleton 0) acc') :}  -} --- | A synchronized signal with samples of type @a@, synchronized to clock--- @clk@, that has accumulated @delay@ amount of samples delay along its path.-newtype DSignal (domain :: Domain) (delay :: Nat) a =-    DSignal { -- | Strip a 'DSignal' from its delay information.-              toSignal :: Signal domain a-            }-  deriving (Show,Default,Functor,Applicative,Num,Fractional,-            Foldable,Traversable,Arbitrary,CoArbitrary,Lift)---- | Create a 'DSignal' from a list------ Every element in the list will correspond to a value of the signal for one--- clock cycle.------ >>> sampleN 2 (dfromList [1,2,3,4,5])--- [1,2]------ __NB__: This function is not synthesisable-dfromList :: NFData a => [a] -> DSignal domain 0 a-dfromList = coerce . fromList---- | Create a 'DSignal' from a list------ Every element in the list will correspond to a value of the signal for one--- clock cycle.------ >>> sampleN 2 (dfromList [1,2,3,4,5])--- [1,2]------ __NB__: This function is not synthesisable-dfromList_lazy :: [a] -> DSignal domain 0 a-dfromList_lazy = coerce . fromList_lazy-+-- TODO: Reimplement with dtfold -- | Delay a 'DSignal' for @d@ periods. -- -- @--- delay3 :: Clock domain gated -> Reset domain synchronous---        -> 'DSignal' domain n Int -> 'DSignal' domain (n + 3) Int--- delay3 clk rst = 'delayed' clk rst (0 ':>' 0 ':>' 0 ':>' 'Nil')+-- delay3+--   :: Clock dom+--   -> Reset dom+--   -> Enable dom+--   -> 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 3) Int+-- delay3 clk rst en = 'delayed' clk rst en (-1 ':>' -1 ':>' -1 ':>' 'Nil') -- @ ----- >>> sampleN 6 (delay3 systemClockGen systemResetGen (dfromList [1..]))--- [0,0,0,1,2,3]+-- >>> sampleN 7 (delay3 systemClockGen resetGen enableGen (dfromList [0..]))+-- [-1,-1,-1,-1,1,2,3] delayed-  :: forall domain gated synchronous a n d-   . KnownNat d-  => Clock domain gated-  -> Reset domain synchronous+  :: forall dom  a n d+   . ( KnownDomain dom+     , KnownNat d+     , NFDataX a )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> Vec d a-  -> DSignal domain n a-  -> DSignal domain (n + d) a-delayed clk rst m ds = coerce (delaySignal (coerce ds))+  -- ^ Initial values+  -> DSignal dom n a+  -> DSignal dom (n + d) a+delayed clk rst en m ds = coerce (delaySignal (coerce ds))   where-    delaySignal :: Signal domain a -> Signal domain a+    delaySignal :: Signal dom a -> Signal dom a     delaySignal s = case length m of       0 -> s       _ -> let (r',o) = shiftInAt0 (unbundle r) (singleton s)-               r      = register clk rst m (bundle r')+               r      = register clk rst en m (bundle r')            in  head o --- | Delay a 'DSignal' for @m@ periods, where @m@ is derived from the+-- | Delay a 'DSignal' for @d@ periods, where @d@ is derived from the -- context. -- -- @--- delay2 :: Clock domain gated -> Reset domain synchronous---        -> 'DSignal' domain n Int -> 'DSignal' domain (n + 2) Int--- delay2 = 'delayI'--- @------ >>> sampleN 6 (delay2 systemClockGen systemResetGen (dfromList [1..]))--- [0,0,1,2,3,4]-delayedI-  :: (Default a, KnownNat d)-  => Clock domain gated-  -> Reset domain synchronous-  -> DSignal domain n a-  -> DSignal domain (n + d) a-delayedI clk rst = delayed clk rst (repeat def)---- | Feed the delayed result of a function back to its input:------ @--- mac :: Clock domain gated -> Reset domain synchronous---     -> 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int--- mac clk rst x y = 'feedback' (mac' x y)---   where---     mac' :: 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int---          -> ('DSignal' domain 0 Int, 'DSignal' domain 1 Int)---     mac' a b acc = let acc' = a * b + acc---                    in  (acc, 'delay' clk rst ('singleton' 0) acc')+-- delay2+--   :: Clock dom+--   -> Reset dom+--   -> Enable dom+--   -> Int+--   -> 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 2) Int+-- delay2 = 'delayedI' -- @ ----- >>> sampleN 6 (mac systemClockGen systemResetGen (dfromList [1..]) (dfromList [1..]))--- [0,1,5,14,30,55]-feedback-  :: (DSignal domain n a -> (DSignal domain n a,DSignal domain (n + m + 1) a))-  -> DSignal domain n a-feedback f = let (o,r) = f (coerce r) in o---- | 'Signal's are not delayed------ > sample s == dsample (fromSignal s)-fromSignal :: Signal domain a -> DSignal domain 0 a-fromSignal = coerce---- | __EXPERIMENTAL__------ __Unsafely__ convert a 'Signal' to /any/ 'DSignal' clk'.------ __NB__: Should only be used to interface with functions specified in terms of--- 'Signal'.-unsafeFromSignal :: Signal domain a -> DSignal domain n a-unsafeFromSignal = DSignal---- | __EXPERIMENTAL__+-- >>> sampleN 7 (delay2 systemClockGen resetGen enableGen (-1) (dfromList ([0..])))+-- [-1,-1,-1,1,2,3,4] ----- Access a /delayed/ signal in the present.+-- @d@ can also be specified using type application: ----- @--- mac :: Clock domain gated -> Reset domain synchronous---     -> 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int -> 'DSignal' domain 0 Int--- mac clk rst x y = acc'---   where---     acc' = (x * y) + 'antiDelay' d1 acc---     acc  = 'delay' clk rst ('singleton' 0) acc'--- @-antiDelay :: SNat d -> DSignal domain (n + d) a -> DSignal domain n a-antiDelay _ = coerce+-- >>> :t delayedI @3+-- delayedI @3+--   :: ... =>+--      Clock dom+--      -> Reset dom+--      -> Enable dom+--      -> a+--      -> DSignal dom n a+--      -> DSignal dom (n + 3) a+delayedI+  :: ( KnownNat d+     , KnownDomain dom+     , NFDataX a )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> a+  -- ^ Initial value+  -> DSignal dom n a+  -> DSignal dom (n + d) a+delayedI clk rst en dflt = delayed clk rst en (repeat dflt)
src/Clash/Explicit/Synchronizer.hs view
@@ -1,6 +1,6 @@ {-| Copyright   :  (C) 2015-2016, University of Twente,-                   2016-2017, Myrtle Software Ltd,+                   2016-2019, Myrtle Software Ltd,                    2017     , Google Inc. License     :  BSD2 (see the file LICENSE) Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>@@ -14,16 +14,7 @@ {-# LANGUAGE TypeApplications      #-} {-# LANGUAGE TypeFamilies          #-} {-# LANGUAGE TypeOperators         #-}-#if !MIN_VERSION_constraints(0,9,0)-{-# LANGUAGE AllowAmbiguousTypes   #-}-{-# LANGUAGE PolyKinds             #-}-#endif--#if MIN_VERSION_constraints(0,9,0)-{-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif+{-# LANGUAGE Safe                  #-}  {-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise       #-} {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}@@ -41,11 +32,7 @@ import Control.Applicative         (liftA2) import Data.Bits                   (complement, shiftR, xor) import Data.Constraint             ((:-)(..), Dict (..))-#if MIN_VERSION_constraints(0,9,0) import Data.Constraint.Nat         (leTrans)-#else-import Unsafe.Coerce-#endif import Data.Maybe                  (isJust) import GHC.TypeLits                (type (+), type (-), type (<=)) @@ -55,20 +42,21 @@ import Clash.Explicit.Mealy        (mealyB) import Clash.Explicit.RAM          (asyncRam) import Clash.Explicit.Signal-  (Clock, Reset, Signal, register, unsafeSynchronizer)+  (Clock, Reset, Signal, Enable, register, unsafeSynchronizer) import Clash.Promoted.Nat          (SNat (..), pow2SNat) import Clash.Promoted.Nat.Literals (d0)-import Clash.Signal                (mux)+import Clash.Signal                (mux, KnownDomain) import Clash.Sized.BitVector       (BitVector, (++#))+import Clash.XException            (NFDataX)  -- * Dual flip-flop synchronizer --- | Synchroniser based on two sequentially connected flip-flops.+-- | Synchronizer based on two sequentially connected flip-flops. -----  * __NB__: This synchroniser can be used for __bit__-synchronization.+--  * __NB__: This synchronizer can be used for __bit__-synchronization. -----  * __NB__: Although this synchroniser does reduce metastability, it does---  not guarantee the proper synchronisation of a whole __word__. For+--  * __NB__: Although this synchronizer does reduce metastability, it does+--  not guarantee the proper synchronization of a whole __word__. For --  example, given that the output is sampled twice as fast as the input is --  running, and we have two samples in the input stream that look like: --@@ -83,111 +71,140 @@ --      Where the level-change of the __msb__ was not captured, but the level --      change of the __lsb__s were. -----      If you want to have /safe/ __word__-synchronisation use+--      If you want to have /safe/ __word__-synchronization use --      'asyncFIFOSynchronizer'. dualFlipFlopSynchronizer-  :: Clock domain1 gated1-  -- ^ 'Clock' to which the incoming  data is synchronised-  -> Clock domain2 gated2-  -- ^ 'Clock' to which the outgoing data is synchronised-  -> Reset domain2 synchronous+  :: ( NFDataX a+     , KnownDomain dom1+     , KnownDomain dom2 )+  => Clock dom1+  -- ^ 'Clock' to which the incoming  data is synchronized+  -> Clock dom2+  -- ^ 'Clock' to which the outgoing data is synchronized+  -> Reset dom2   -- ^ 'Reset' for registers on the outgoing domain+  -> Enable dom2+  -- ^ 'Enable' for registers on the outgoing domain   -> a-  -- ^ Initial value of the two synchronisation registers-  -> Signal domain1 a -- ^ Incoming data-  -> Signal domain2 a -- ^ Outgoing, synchronised, data-dualFlipFlopSynchronizer clk1 clk2 rst i =-  register clk2 rst i . register clk2 rst i . unsafeSynchronizer clk1 clk2+  -- ^ Initial value of the two synchronization registers+  -> Signal dom1 a+  -- ^ Incoming data+  -> Signal dom2 a+  -- ^ Outgoing, synchronized, data+dualFlipFlopSynchronizer clk1 clk2 rst en i =+  register clk2 rst en i+    . register clk2 rst en i+    . unsafeSynchronizer clk1 clk2  -- * Asynchronous FIFO synchronizer  fifoMem-  :: Clock wdomain wgated-  -> Clock rdomain rgated+  :: ( KnownDomain wdom+     , KnownDomain rdom )+  => Clock wdom+  -> Clock rdom+  -> Enable wdom   -> SNat addrSize-  -> Signal wdomain Bool-  -> Signal rdomain (BitVector addrSize)-  -> Signal wdomain (Maybe (BitVector addrSize, a))-  -> Signal rdomain a-fifoMem wclk rclk addrSize@SNat full raddr writeM =-  asyncRam wclk rclk-           (pow2SNat addrSize)-           raddr-           (mux full (pure Nothing) writeM)+  -> Signal wdom Bool+  -> Signal rdom (BitVector addrSize)+  -> Signal wdom (Maybe (BitVector addrSize, a))+  -> Signal rdom a+fifoMem wclk rclk en addrSize@SNat full raddr writeM =+  asyncRam+    wclk rclk en+    (pow2SNat addrSize)+    raddr+    (mux full (pure Nothing) writeM) -ptrCompareT :: SNat addrSize-            -> (BitVector (addrSize + 1) -> BitVector (addrSize + 1) -> Bool)-            -> (BitVector (addrSize + 1), BitVector (addrSize + 1), Bool)-            -> (BitVector (addrSize + 1), Bool)-            -> ((BitVector (addrSize + 1), BitVector (addrSize + 1), Bool)-               ,(Bool, BitVector addrSize, BitVector (addrSize + 1)))-ptrCompareT SNat flagGen (bin,ptr,flag) (s_ptr,inc) = ((bin',ptr',flag')-                                                      ,(flag,addr,ptr))-  where-    -- GRAYSTYLE2 pointer-    bin' = bin + boolToBV (inc && not flag)-    ptr' = (bin' `shiftR` 1) `xor` bin'-    addr = truncateB bin+ptrCompareT+  :: SNat addrSize+  -> (BitVector (addrSize + 1) -> BitVector (addrSize + 1) -> Bool)+  -> ( BitVector (addrSize + 1)+     , BitVector (addrSize + 1)+     , Bool )+  -> ( BitVector (addrSize + 1)+     , Bool )+  -> ( ( BitVector (addrSize + 1)+       , BitVector (addrSize + 1)+       , Bool )+     , ( Bool+       , BitVector addrSize+       , BitVector (addrSize + 1)+       )+     )+ptrCompareT SNat flagGen (bin, ptr, flag) (s_ptr, inc) =+  ((bin', ptr', flag'), (flag, addr, ptr))+ where+  -- GRAYSTYLE2 pointer+  bin' = bin + boolToBV (inc && not flag)+  ptr' = (bin' `shiftR` 1) `xor` bin'+  addr = truncateB bin -    flag' = flagGen ptr' s_ptr+  flag' = flagGen ptr' s_ptr  -- FIFO full: when next pntr == synchonized {~wptr[addrSize:addrSize-1],wptr[addrSize-1:0]}-isFull :: forall addrSize .-          (2 <= addrSize)-       => SNat addrSize-       -> BitVector (addrSize + 1)-       -> BitVector (addrSize + 1)-       -> Bool-isFull addrSize@SNat ptr s_ptr = case leTrans @1 @2 @addrSize of-  Sub Dict ->-    let a1 = SNat @(addrSize - 1)-        a2 = SNat @(addrSize - 2)-    in  ptr == (complement (slice addrSize a1 s_ptr) ++# slice a2 d0 s_ptr)+isFull+  :: forall addrSize+   . (2 <= addrSize)+  => SNat addrSize+  -> BitVector (addrSize + 1)+  -> BitVector (addrSize + 1)+  -> Bool+isFull addrSize@SNat ptr s_ptr =+  case leTrans @1 @2 @addrSize of+    Sub Dict ->+      let a1 = SNat @(addrSize - 1)+          a2 = SNat @(addrSize - 2)+      in  ptr == (complement (slice addrSize a1 s_ptr) ++# slice a2 d0 s_ptr) --- | Synchroniser implemented as a FIFO around an asynchronous RAM. Based on the+-- | Synchronizer implemented as a FIFO around an asynchronous RAM. Based on the -- design described in "Clash.Tutorial#multiclock", which is itself based on the -- design described in <http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf>. ----- __NB__: This synchroniser can be used for __word__-synchronization.+-- __NB__: This synchronizer can be used for __word__-synchronization. asyncFIFOSynchronizer-  :: (2 <= addrSize)+  :: ( KnownDomain wdom+     , KnownDomain rdom+     , 2 <= addrSize )   => SNat addrSize   -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@   -- elements.-  -> Clock wdomain wgated-  -- ^ 'Clock' to which the write port is synchronised-  -> Clock rdomain rgated-  -- ^ 'Clock' to which the read port is synchronised-  -> Reset wdomain synchronous-  -> Reset rdomain synchronous-  -> Signal rdomain Bool+  -> Clock wdom+  -- ^ 'Clock' to which the write port is synchronized+  -> Clock rdom+  -- ^ 'Clock' to which the read port is synchronized+  -> Reset wdom+  -> Reset rdom+  -> Enable wdom+  -> Enable rdom+  -> Signal rdom Bool   -- ^ Read request-  -> Signal wdomain (Maybe a)+  -> Signal wdom (Maybe a)   -- ^ Element to insert-  -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)+  -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)   -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)-asyncFIFOSynchronizer addrSize@SNat wclk rclk wrst rrst rinc wdataM =-    (rdata,rempty,wfull)-  where-    s_rptr = dualFlipFlopSynchronizer rclk wclk wrst 0 rptr-    s_wptr = dualFlipFlopSynchronizer wclk rclk rrst 0 wptr--    rdata = fifoMem wclk rclk addrSize wfull raddr-              (liftA2 (,) <$> (pure <$> waddr) <*> wdataM)--    (rempty,raddr,rptr) = mealyB rclk rrst (ptrCompareT addrSize (==)) (0,0,True)-                                 (s_wptr,rinc)--    (wfull,waddr,wptr)  = mealyB wclk wrst (ptrCompareT addrSize (isFull addrSize))-                                 (0,0,False) (s_rptr,isJust <$> wdataM)+asyncFIFOSynchronizer addrSize@SNat wclk rclk wrst rrst wen ren rinc wdataM =+  (rdata, rempty, wfull)+ where+  s_rptr = dualFlipFlopSynchronizer rclk wclk wrst wen 0 rptr+  s_wptr = dualFlipFlopSynchronizer wclk rclk rrst ren 0 wptr -#if !MIN_VERSION_constraints(0,9,0)-axiom :: forall a b . Dict (a ~ b)-axiom = unsafeCoerce (Dict :: Dict (a ~ a))+  rdata =+    fifoMem+      wclk rclk wen+      addrSize wfull raddr+      (liftA2 (,) <$> (pure <$> waddr) <*> wdataM) -axiomLe :: forall a b. Dict (a <= b)-axiomLe = axiom+  (rempty, raddr, rptr) =+    mealyB+      rclk rrst ren+      (ptrCompareT addrSize (==))+      (0, 0, True)+      (s_wptr, rinc) -leTrans :: forall a b c. (b <= c, a <= b) :- (a <= c)-leTrans = Sub (axiomLe @a @c)-#endif+  (wfull, waddr, wptr) =+    mealyB+      wclk wrst wen+      (ptrCompareT addrSize (isFull addrSize))+      (0, 0, False)+      (s_rptr, isJust <$> wdataM)
src/Clash/Explicit/Testbench.hs view
@@ -1,60 +1,98 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} +{-# LANGUAGE BangPatterns        #-}+{-# LANGUAGE DataKinds           #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE TypeOperators       #-}  {-# LANGUAGE Unsafe #-}  {-# OPTIONS_HADDOCK show-extensions #-} +{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}+ module Clash.Explicit.Testbench   ( -- * Testbench functions for circuits     assert+  , ignoreFor   , stimuliGenerator++  , tbClockGen+  , tbEnableGen+  , tbSystemClockGen+   , outputVerifier+  , outputVerifier'+  , outputVerifierBitVector+  , outputVerifierBitVector'+  , biTbClockGen   ) where  import Control.Exception     (catch, evaluate) import Debug.Trace           (trace)-import GHC.TypeLits          (KnownNat)+import GHC.TypeLits          (KnownNat, type (+)) import Prelude               hiding ((!!), length) import System.IO.Unsafe      (unsafeDupablePerformIO) +import Clash.Annotations.Primitive (hasBlackBox)+import Clash.Class.Num       (satSucc, SaturationMode(SatBound))+import Clash.Promoted.Nat    (SNat(..), snatToNum)+import Clash.Promoted.Symbol (SSymbol (..)) import Clash.Explicit.Signal-  (Clock, Reset, Signal, fromList, register, unbundle)+  (Clock, Reset, System, Signal, clockPeriod, toEnable, fromList, register,+  unbundle, unsafeSynchronizer, veryUnsafeSynchronizer)+import Clash.Signal.Internal (Clock (..))+import Clash.Signal+  (mux, DomainResetKind, ResetKind(Asynchronous), KnownDomain, Reset(..),+  Enable) import Clash.Sized.Index     (Index)+import Clash.Sized.Internal.BitVector+  (BitVector, isLike) import Clash.Sized.Vector    (Vec, (!!), length) import Clash.XException      (ShowX (..), XException) +-- Note that outputVerifier' is used in $setup, while the examples mention+-- outputVerifier. This is fine, as the examples have explicit type+-- signatures, turning 'outputVerifier' into 'outputVerifier''.+ {- $setup->>> :set -XTemplateHaskell -XDataKinds+>>> :set -XTemplateHaskell -XDataKinds -XTypeFamilies >>> import Clash.Explicit.Prelude >>> let testInput clk rst = stimuliGenerator clk rst $(listToVecTH [(1::Int),3..21])->>> let expectedOutput clk rst = outputVerifier clk rst $(listToVecTH ([70,99,2,3,4,5,7,8,9,10]::[Int]))+>>> let expectedOutput clk rst = outputVerifier' clk rst $(listToVecTH ([70,99,2,3,4,5,7,8,9,10]::[Int])) -}  -- | Compares the first two 'Signal's for equality and logs a warning when they -- are not equal. The second 'Signal' is considered the expected value. This--- function simply returns the third 'Signal'' unaltered as its result. This+-- function simply returns the third 'Signal' unaltered as its result. This -- function is used by 'outputVerifier'. -- -- -- __NB__: This function /can/ be used in synthesizable designs. assert-  :: (Eq a,ShowX a)-  => Clock domain gated-  -> Reset domain synchronous-  -> String      -- ^ Additional message-  -> Signal domain a -- ^ Checked value-  -> Signal domain a -- ^ Expected value-  -> Signal domain b -- ^ Return value-  -> Signal domain b-assert clk _rst msg checked expected returned =+  :: (KnownDomain dom, Eq a, ShowX a)+  => Clock dom+  -> Reset dom+  -> String+  -- ^ Additional message+  -> Signal dom a+  -- ^ Checked value+  -> Signal dom a+  -- ^ Expected value+  -> Signal dom b+  -- ^ Return value+  -> Signal dom b+assert clk (Reset _) msg checked expected returned =   (\c e cnt r ->       if eqX c e          then r@@ -72,32 +110,72 @@     eqX a b = unsafeDupablePerformIO (catch (evaluate (a == b))                                             (\(_ :: XException) -> return False)) {-# NOINLINE assert #-}+{-# ANN assert hasBlackBox #-} --- | To be used as one of the functions to create the \"magical\" 'testInput'--- value, which the CλaSH compiler looks for to create the stimulus generator--- for the generated VHDL testbench.+-- | The same as 'assert', but can handle don't care bits in it's expected value.+assertBitVector+  :: (KnownDomain dom, KnownNat n)+  => Clock dom+  -> Reset dom+  -> String+  -- ^ Additional message+  -> Signal dom (BitVector n)+  -- ^ Checked value+  -> Signal dom (BitVector n)+  -- ^ Expected value+  -> Signal dom b+  -- ^ Return value+  -> Signal dom b+assertBitVector clk (Reset _) msg checked expected returned =+  (\c e cnt r ->+      if eqX c e+         then r+         else trace (concat [ "\ncycle(" ++ show clk ++ "): "+                            , show cnt+                            , ", "+                            , msg+                            , "\nexpected value: "+                            , showX e+                            , ", not equal to actual value: "+                            , showX c+                            ]) r)+  <$> checked <*> expected <*> fromList [(0::Integer)..] <*> returned+  where+    eqX a b = unsafeDupablePerformIO (catch (evaluate (a `isLike` b))+                                            (\(_ :: XException) -> return False))+{-# NOINLINE assertBitVector #-}+{-# ANN assertBitVector hasBlackBox #-}++++-- | -- -- Example: -- -- @ -- testInput---   :: Clock domain gated -> Reset domain synchronous---   -> 'Signal' domain Int+--   :: KnownDomain dom+--   => Clock dom+--   -> Reset dom+--   -> 'Signal' dom Int -- testInput clk rst = 'stimuliGenerator' clk rst $('Clash.Sized.Vector.listToVecTH' [(1::Int),3..21]) -- @ ----- >>> sampleN 13 (testInput systemClockGen systemResetGen)--- [1,3,5,7,9,11,13,15,17,19,21,21,21]+-- >>> sampleN 14 (testInput systemClockGen resetGen)+-- [1,1,3,5,7,9,11,13,15,17,19,21,21,21] stimuliGenerator-  :: forall l domain gated synchronous a-   . KnownNat l-  => Clock domain gated+  :: forall l dom   a+   . ( KnownNat l+     , KnownDomain dom )+  => Clock dom   -- ^ Clock to which to synchronize the output signal-  -> Reset domain synchronous-  -> Vec l a        -- ^ Samples to generate-  -> Signal domain a  -- ^ Signal of given samples+  -> Reset dom+  -> Vec l a+  -- ^ Samples to generate+  -> Signal dom a+  -- ^ Signal of given samples stimuliGenerator clk rst samples =-    let (r,o) = unbundle (genT <$> register clk rst 0 r)+    let (r,o) = unbundle (genT <$> register clk rst (toEnable (pure True)) 0 r)     in  o   where     genT :: Index l -> (Index l,a)@@ -110,53 +188,99 @@                 else s {-# INLINABLE stimuliGenerator #-} --- | To be used as one of the functions to generate the \"magical\" 'expectedOutput'--- function, which the CλaSH compiler looks for to create the signal verifier--- for the generated VHDL testbench.+-- | Same as 'outputVerifier' but used in cases where the testbench domain and+-- the domain of the circuit under test are the same.+outputVerifier'+  :: forall l a dom+   . ( KnownNat l+     , KnownDomain dom+     , DomainResetKind dom ~ 'Asynchronous+     , Eq a+     , ShowX a )+  => Clock dom+  -- ^ Clock to which the testbench is synchronized to+  -> Reset dom+  -- ^ Reset line of testbench+  -> Vec l a+  -- ^ Samples to compare with+  -> Signal dom a+  -- ^ Signal to verify+  -> Signal dom Bool+  -- ^ Indicator that all samples are verified+outputVerifier' =+  outputVerifier @l @a @dom @dom+{-# INLINABLE outputVerifier' #-}++-- | Compare a signal (coming from a circuit) to a vector of samples. If a+-- sample from the signal is not equal to the corresponding sample in the+-- vector, print to stderr and continue testing. This function is+-- synthesizable in the sense that HDL simulators will run it. -- -- Example: -- -- @ -- expectedOutput---   :: Clock domain gated -> Reset domain synchronous---   -> 'Signal' domain Int -> 'Signal' domain Bool+--   :: Clock dom -> Reset dom+--   -> 'Signal' dom Int -> 'Signal' dom Bool -- expectedOutput clk rst = 'outputVerifier' clk rst $('Clash.Sized.Vector.listToVecTH' ([70,99,2,3,4,5,7,8,9,10]::[Int])) -- @ -- -- >>> import qualified Data.List as List--- >>> sampleN 12 (expectedOutput systemClockGen systemResetGen (fromList ([0..10] List.++ [10,10,10])))+-- >>> sampleN 12 (expectedOutput systemClockGen resetGen (fromList (0:[0..10] List.++ [10,10,10]))) -- <BLANKLINE>--- cycle(system10000): 0, outputVerifier+-- cycle(<Clock: System>): 0, outputVerifier -- expected value: 70, not equal to actual value: 0 -- [False--- cycle(system10000): 1, outputVerifier+-- cycle(<Clock: System>): 1, outputVerifier+-- expected value: 70, not equal to actual value: 0+-- ,False+-- cycle(<Clock: System>): 2, outputVerifier -- expected value: 99, not equal to actual value: 1 -- ,False,False,False,False,False--- cycle(system10000): 6, outputVerifier+-- cycle(<Clock: System>): 7, outputVerifier -- expected value: 7, not equal to actual value: 6 -- ,False--- cycle(system10000): 7, outputVerifier+-- cycle(<Clock: System>): 8, outputVerifier -- expected value: 8, not equal to actual value: 7 -- ,False--- cycle(system10000): 8, outputVerifier+-- cycle(<Clock: System>): 9, outputVerifier -- expected value: 9, not equal to actual value: 8 -- ,False--- cycle(system10000): 9, outputVerifier+-- cycle(<Clock: System>): 10, outputVerifier -- expected value: 10, not equal to actual value: 9--- ,False,True,True]+-- ,False,True]+--+-- If your working with 'BitVector's containing don't care bits you should+-- use 'outputVerifierBitVector'. outputVerifier-  :: forall l domain gated synchronous a-   . (KnownNat l, Eq a, ShowX a)-  => Clock domain gated-  -- ^ Clock to which the input signal is synchronized to-  -> Reset domain synchronous-  -> Vec l a          -- ^ Samples to compare with-  -> Signal domain a    -- ^ Signal to verify-  -> Signal domain Bool -- ^ Indicator that all samples are verified-outputVerifier clk rst samples i =-    let (s,o) = unbundle (genT <$> register clk rst 0 s)+  :: forall l a testDom circuitDom+   . ( KnownNat l+     , KnownDomain testDom+     , KnownDomain circuitDom+     , DomainResetKind testDom ~ 'Asynchronous+     , Eq a+     , ShowX a )+  => Clock testDom+  -- ^ Clock to which the testbench is synchronized to (but not necessarily+  -- the circuit under test)+  -> Reset testDom+  -- ^ Reset line of testbench+  -> Vec l a+  -- ^ Samples to compare with+  -> Signal circuitDom a+  -- ^ Signal to verify+  -> Signal testDom Bool+  -- ^ True if all samples are verified+outputVerifier clk rst samples i0 =+    let t1    = snatToNum (clockPeriod @circuitDom)+        t2    = snatToNum (clockPeriod @testDom)+        i1    = veryUnsafeSynchronizer t1 t2 i0+        en    = toEnable (pure True)+        (s,o) = unbundle (genT <$> register clk rst en 0 s)         (e,f) = unbundle o-    in  assert clk rst "outputVerifier" i e (register clk rst False f)+        f'    = register clk rst en False f+        -- Only assert while not finished+    in  mux f' f' $ assert clk rst "outputVerifier" i1 e f'   where     genT :: Index l -> (Index l,(a,Bool))     genT s = (s',(samples !! s,finished))@@ -169,3 +293,193 @@          finished = s == maxI {-# INLINABLE outputVerifier #-}++-- | Same as 'outputVerifier'', but can handle don't care bits in it's expected+-- values.+outputVerifierBitVector'+  :: forall l n dom+   . ( KnownNat l+     , KnownNat n+     , KnownDomain dom+     , DomainResetKind dom ~ 'Asynchronous+     )+  => Clock dom+  -- ^ Clock to which the input signal is synchronized to+  -> Reset dom+  -> Vec l (BitVector n)+  -- ^ Samples to compare with+  -> Signal dom (BitVector n)+  -- ^ Signal to verify+  -> Signal dom Bool+  -- ^ Indicator that all samples are verified+outputVerifierBitVector' =+  outputVerifierBitVector @l @n @dom @dom+{-# INLINABLE outputVerifierBitVector' #-}++-- | Same as 'outputVerifier', but can handle don't care bits in it's+-- expected values.+outputVerifierBitVector+  :: forall l n testDom circuitDom+   . ( KnownNat l+     , KnownNat n+     , KnownDomain testDom+     , KnownDomain circuitDom+     , DomainResetKind testDom ~ 'Asynchronous+     )+  => Clock testDom+  -- ^ Clock to which the input signal is synchronized to+  -> Reset testDom+  -> Vec l (BitVector n)+  -- ^ Samples to compare with+  -> Signal circuitDom (BitVector n)+  -- ^ Signal to verify+  -> Signal testDom Bool+  -- ^ Indicator that all samples are verified+outputVerifierBitVector clk rst samples i0 =+    let t1    = snatToNum (clockPeriod @circuitDom)+        t2    = snatToNum (clockPeriod @testDom)+        i1    = veryUnsafeSynchronizer t1 t2 i0+        en    = toEnable (pure True)+        (s,o) = unbundle (genT <$> register clk rst en 0 s)+        (e,f) = unbundle o+        f'    = register clk rst en False f+        -- Only assert while not finished+    in  mux f' f' $ assertBitVector clk rst "outputVerifierBitVector'" i1 e f'+  where+    genT :: Index l -> (Index l,(BitVector n,Bool))+    genT s = (s',(samples !! s,finished))+      where+        maxI = toEnum (length samples - 1)++        s' = if s < maxI+                then s + 1+                else s++        finished = s == maxI+{-# INLINABLE outputVerifierBitVector #-}++-- | Ignore signal for a number of cycles, while outputting a static value.+ignoreFor+  :: forall dom  n a+   . KnownDomain dom+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> SNat n+  -- ^ Number of cycles to ignore incoming signal+  -> a+  -- ^ Value function produces when ignoring signal+  -> Signal dom a+  -- ^ Incoming signal+  -> Signal dom a+  -- ^ Either a passthrough of the incoming signal, or the static value+  -- provided as the second argument.+ignoreFor clk rst en SNat a i =+  mux ((==) <$> counter <*> (pure maxBound)) i (pure a)+ where+  counter :: Signal dom (Index (n+1))+  counter = register clk rst en 0 (satSucc SatBound <$> counter)++-- | Same as 'tbClockGen', but returns two clocks on potentially different+-- domains. To be used in situations where the circuit under test runs+-- in a different domain than the circuit testing it. Most commonly used+-- to test synchronous circuits (with an asynchronous test circuit).+biTbClockGen+  :: forall testDom circuitDom+   . ( KnownDomain testDom+     , KnownDomain circuitDom+     , DomainResetKind testDom ~ 'Asynchronous+     )+  => Signal testDom Bool+  -> (Clock testDom, Clock circuitDom)+biTbClockGen done = (testClk, circuitClk)+ where+  testClk = tbClockGen done+  circuitClk = tbClockGen (unsafeSynchronizer testClk circuitClk done)++-- | Clock generator to be used in the /testBench/ function.+--+-- To be used like:+--+-- @+-- clkSystem en = tbClockGen @System en+-- @+--+-- === __Example__+--+-- @+-- module Example where+--+-- import "Clash.Explicit.Prelude"+-- import "Clash.Explicit.Testbench"+--+-- -- Fast domain: twice as fast as \"Slow\"+-- 'createDomain' 'vSystem'{vName=\"Fast\", vPeriod=10}+--+-- -- Slow domain: twice as slow as "Fast"+-- 'createDomain' 'vSystem'{vName=\"Slow\", vPeriod=20}+--+-- topEntity+--   :: 'Clock' \"Fast\"+--   -> 'Reset' \"Fast\"+--   -> 'Enable' \"Fast\"+--   -> 'Clock' \"Slow\"+--   -> 'Signal' \"Fast\" (Unsigned 8)+--   -> 'Signal' \"Slow\" (Unsigned 8, Unsigned 8)+-- topEntity clk1 rst1 en1 clk2 i =+--   let h = register clk1 rst1 en1 0 (register clk1 rst1 en1 0 i)+--       l = register clk1 rst1 en1 0 i+--   in  unsafeSynchronizer clk1 clk2 (bundle (h, l))+--+-- testBench+--   :: 'Signal' \"Slow\" Bool+-- testBench = done+--   where+--     testInput      = 'Clash.Explicit.Testbench.stimuliGenerator' clkA1 rstA1 $('listToVecTH' [1::Unsigned 8,2,3,4,5,6,7,8])+--     expectedOutput = 'Clash.Explicit.Testbench.outputVerifier'   clkB2 rstB2 $('listToVecTH' [(0,0) :: (Unsigned 8, Unsigned 8),(1,2),(3,4),(5,6),(7,8)])+--     done           = expectedOutput (topEntity clkA1 rstA1 enableGen clkB2 testInput)+--     done'          = not \<$\> done+--     clkA1          = 'tbClockGen' \@\"Fast\" (unsafeSynchronizer clkB2 clkA1 done')+--     clkB2          = 'tbClockGen' \@\"Slow\" done'+--     rstA1          = 'resetGen' \@\"Fast\"+--     rstB2          = 'resetGen' \@\"Slow\"+-- @+tbClockGen+  :: KnownDomain testDom+  => Signal testDom Bool+  -> Clock testDom+tbClockGen done = Clock (done `seq` SSymbol)+{-# NOINLINE tbClockGen #-}+{-# ANN tbClockGen hasBlackBox #-}++-- | Enable signal that's always enabled. Because it has a blackbox definition+-- this enable signal is opaque to other blackboxes. It will therefore never+-- be optimized away.+tbEnableGen :: Enable tag+tbEnableGen = toEnable (pure True)+{-# NOINLINE tbEnableGen #-}+{-# ANN tbEnableGen hasBlackBox #-}++-- | Clock generator for the 'System' clock domain.+--+-- __NB__: can be used in the /testBench/ function+--+-- === __Example__+--+-- @+-- topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)+-- topEntity = concat+--+-- testBench :: Signal System Bool+-- testBench = done+--   where+--     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)+--     expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)+--     done           = exposeClockResetEnable (expectedOutput (topEntity <$> testInput)) clk rst+--     clk            = 'tbSystemClockGen' (not <\$\> done)+--     rst            = systemResetGen+-- @+tbSystemClockGen+  :: Signal System Bool+  -> Clock System+tbSystemClockGen = tbClockGen
+ src/Clash/HaskellPrelude.hs view
@@ -0,0 +1,23 @@+{-|+  Copyright   :  (C) 2019, QBayLogic B.V.+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  QBayLogic B.V <devops@qbaylogic.com>++"Clash.HaskellPrelude" re-exports most of the Haskell "Prelude" with the exception of+the following: (++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head,+init, iterate, last, length, map, repeat, replicate, reverse, scanl, scanr,+splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3.+-}++{-# LANGUAGE Safe #-}++{-# OPTIONS_HADDOCK show-extensions, not-home #-}++module Clash.HaskellPrelude+  (module Prelude)+where++import Prelude hiding+  ((++), (!!), concat, concatMap, drop, foldl, foldl1, foldr, foldr1, head, init,+   iterate, last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt,+   tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined, (^))
src/Clash/Intel/ClockGen.hs view
@@ -1,20 +1,27 @@ {-|-Copyright  :  (C) 2017, Google Inc+Copyright  :  (C) 2017-2018, Google Inc+                  2019     , Myrtle Software License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  PLL and other clock-related components for Intel (Altera) FPGAs -} -{-# LANGUAGE DataKinds      #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE GADTs          #-}-module Clash.Intel.ClockGen where+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE ExplicitForAll    #-} -import Clash.Promoted.Symbol+module Clash.Intel.ClockGen+  ( altpll+  , alteraPll+  ) where++import Clash.Clocks           (clocks, Clocks)+import Clash.Promoted.Symbol  (SSymbol) import Clash.Signal.Internal-import Unsafe.Coerce+  (Signal, Clock, Reset) + -- | A clock source that corresponds to the Intel/Quartus \"ALTPLL\" component -- with settings to provide a stable 'Clock' from a single free-running input --@@ -28,27 +35,25 @@ -- You must use type applications to specify the output clock domain, e.g.: -- -- @--- type Dom100MHz = Dom \"A\" 10000--- -- -- outputs a clock running at 100 MHz--- altpll @@Dom100MHz (SSymbol @@"altpll50to100") clk50 rst+-- altpll @@"50MHzDom" @@"100MHzDom" (SSymbol @@"altpll50to100") clk50 rst -- @ altpll-  :: forall pllOut pllIn name+  :: forall domOut domIn name    . SSymbol name   -- ^ Name of the component, must correspond to the name entered in the QSys   -- dialog.   --   -- For example, when you entered \"altPLL50\", instantiate as follows:   ---  -- > SSymbol @ "altPLL50"-  -> Clock  pllIn 'Source+  -- > SSymbol @"altPLL50"+  -> Clock domIn   -- ^ Free running clock (i.e. a clock pin connected to a crystal)-  -> Reset  pllIn 'Asynchronous+  -> Reset domIn   -- ^ Reset for the PLL-  -> (Clock pllOut 'Source, Signal pllOut Bool)+  -> (Clock domOut, Signal domOut Bool)   -- ^ (Stable PLL clock, PLL lock)-altpll _ clk (Async rst) = (unsafeCoerce (clockGate clk rst), unsafeCoerce rst)+altpll _ = clocks {-# NOINLINE altpll #-}  -- | A clock source that corresponds to the Intel/Quartus \"Altera PLL\"@@ -58,33 +63,37 @@ -- Only works when configured with: -- -- * 1 reference clock--- * 1 output clock--- * a reset port--- * a locked port+-- * 1-16 output clocks+-- * a reset input port+-- * a locked output port ----- You must use type applications to specify the output clock domain, e.g.:+-- The number of output clocks depend this function's inferred result type. An+-- instance with a single and double output clock can be instantiated using: -- -- @--- type Dom100MHz = Dom \"A\" 10000+-- (outClk, pllLocked) = alteraPll clk rst+-- @ ----- -- outputs a clock running at 100 MHz--- alteraPll @@Dom100MHz (SSymbol @@"alteraPll50to100") clk50 rst+-- and+-- -- @+-- (outClk1, outClk2, pllLocked) = alteraPll clk rst+-- @+--+-- respectively. alteraPll-  :: forall pllOut pllIn name-   . SSymbol name+  :: Clocks t+  => SSymbol name   -- ^ Name of the component, must correspond to the name entered in the QSys   -- dialog.   --   -- For example, when you entered \"alteraPLL50\", instantiate as follows:   ---  -- > SSymbol @ "alteraPLL50"-  -> Clock pllIn 'Source+  -- > SSymbol @"alteraPLL50"+  -> Clock domIn   -- ^ Free running clock (i.e. a clock pin connected to a crystal)-  -> Reset pllIn 'Asynchronous+  -> Reset domIn   -- ^ Reset for the PLL-  -> (Clock pllOut 'Source, Signal pllOut Bool)-  -- ^ (Stable PLL clock, PLL lock)-alteraPll _ clk (Async rst) =-  (unsafeCoerce (clockGate clk rst), unsafeCoerce rst)+  -> t+alteraPll _ = clocks {-# NOINLINE alteraPll #-}
src/Clash/Intel/DDR.hs view
@@ -1,5 +1,6 @@ {-| Copyright  :  (C) 2017, Google Inc+                  2019, Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -7,16 +8,20 @@  For general information about DDR primitives see "Clash.Explicit.DDR". -Note that a synchronous reset is only available on certain devices,+Note that a reset is only available on certain devices, see ALTDDIO userguide for the specifics:-https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_altddio.pdf+<https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_altddio.pdf> -} +{-# LANGUAGE CPP              #-} {-# LANGUAGE DataKinds        #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MagicHash        #-} {-# LANGUAGE TypeFamilies     #-} {-# LANGUAGE TypeOperators    #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  module Clash.Intel.DDR   ( altddioIn@@ -26,6 +31,7 @@  import GHC.Stack (HasCallStack, withFrozenCallStack) +import Clash.Annotations.Primitive (hasBlackBox) import Clash.Explicit.Prelude import Clash.Explicit.DDR @@ -34,8 +40,8 @@ -- Reset values are @0@ altddioIn   :: ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast)+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)      , KnownNat m )   => SSymbol deviceFamily   -- ^ The FPGA family@@ -43,24 +49,27 @@   -- For example this can be instantiated as follows:   --   -- > SSymbol @"Cyclone IV GX"-  -> Clock slow gated+  -> Clock slow   -- ^ clock-  -> Reset slow synchronous+  -> Reset slow   -- ^ reset+  -> Enable slow+  -- ^ Global enable   -> Signal fast (BitVector m)   -- ^ DDR input signal   -> Signal slow (BitVector m,BitVector m)   -- ^ normal speed output pairs-altddioIn _devFam clk rst = withFrozenCallStack ddrIn# clk rst 0 0 0+altddioIn _devFam clk rst en = withFrozenCallStack ddrIn# clk rst en 0 0 0 {-# NOINLINE altddioIn #-}+{-# ANN altddioIn hasBlackBox #-}  -- | Intel specific variant of 'ddrOut' implemented using the ALTDDIO_OUT IP core. -- -- Reset value is @0@ altddioOut   :: ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast)+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)      , KnownNat m )   => SSymbol deviceFamily   -- ^ The FPGA family@@ -68,27 +77,31 @@   -- For example this can be instantiated as follows:   --   -- > SSymbol @"Cyclone IV E"-  -> Clock slow gated+  -> Clock slow   -- ^ clock-  -> Reset slow synchronous+  -> Reset slow   -- ^ reset+  -> Enable slow+  -- ^ Global enable   -> Signal slow (BitVector m,BitVector m)   -- ^ normal speed input pair   -> Signal fast (BitVector m)   -- ^ DDR output signal-altddioOut devFam clk rst =-  uncurry (withFrozenCallStack altddioOut# devFam clk rst) . unbundle+altddioOut devFam clk rst en =+  uncurry (withFrozenCallStack altddioOut# devFam clk rst en) . unbundle  altddioOut#   :: ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast)+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)      , KnownNat m )   => SSymbol deviceFamily-  -> Clock slow gated-  -> Reset slow synchronous+  -> Clock slow+  -> Reset slow+  -> Enable slow   -> Signal slow (BitVector m)   -> Signal slow (BitVector m)   -> Signal fast (BitVector m)-altddioOut# _ clk rst = ddrOut# clk rst 0+altddioOut# _ clk rst en = ddrOut# clk rst en 0 {-# NOINLINE altddioOut# #-}+{-# ANN altddioOut# hasBlackBox #-}
+ src/Clash/Magic.hs view
@@ -0,0 +1,38 @@+{-|+  Copyright   :  (C) 2019, Myrtle Software Ltd+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  QBayLogic B.V. <clash@qbaylogic.com>++Control module instance, and register, names in generated HDL code.+-}++{-# LANGUAGE DataKinds      #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeOperators  #-}++module Clash.Magic where++import Clash.NamedTypes ((:::))+import GHC.TypeLits     (Symbol)++-- | Prefix instance and register names with the given 'Symbol'+prefixName+  :: forall (name :: Symbol) a . a -> name ::: a+prefixName = id+{-# NOINLINE prefixName #-}++-- | Suffix instance and register names with the given 'Symbol'+suffixName+  :: forall (name :: Symbol) a . a -> name ::: a+suffixName = id+{-# NOINLINE suffixName #-}++-- | Name the instance or register with the given 'Symbol', instead of using+-- an auto-generated name. Pre- and suffixes annotated with 'prefixName' and+-- 'suffixName' will be added to both instances and registers named with+-- 'setName' and instances and registers that are auto-named.+setName+  :: forall (name :: Symbol) a . a -> name ::: a+setName = id+{-# NOINLINE setName #-}
src/Clash/NamedTypes.hs view
@@ -7,23 +7,24 @@  @ fifo-  :: Clock domain gated-  -> Reset domain synchronous+  :: Clock dom+  -> Reset dom   -> SNat addrSize-  -> "read request" ::: Signal domain Bool-  -> "write request" ::: Signal domain (Maybe (BitVector dataSize))-  -> ( "q"     ::: Signal domain (BitVector dataSize)-     , "full"  ::: Signal domain Bool-     , "empty" ::: Signal domain Bool+  -> "read request" ::: Signal dom Bool+  -> "write request" ::: Signal dom (Maybe (BitVector dataSize))+  -> ( "q"     ::: Signal dom (BitVector dataSize)+     , "full"  ::: Signal dom Bool+     , "empty" ::: Signal dom Bool      ) @  which can subsequently be inspected in the interactive environment: +>>> import Clash.Explicit.Prelude >>> :t fifo @System fifo @System-  :: Clock System gated-     -> Reset System synchronous+  :: Clock System+     -> Reset System      -> SNat addrSize      -> ("read request" ::: Signal System Bool)      -> ("write request" ::: Signal System (Maybe (BitVector dataSize)))@@ -51,14 +52,14 @@ >>> import Clash.Explicit.Prelude >>> :{ let fifo-      :: Clock domain gated-      -> Reset domain synchronous+      :: Clock dom+      -> Reset dom       -> SNat addrSize-      -> "read request" ::: Signal domain Bool-      -> "write request" ::: Signal domain (Maybe (BitVector dataSize))-      -> ( "q"     ::: Signal domain (BitVector dataSize)-         , "full"  ::: Signal domain Bool-         , "empty" ::: Signal domain Bool+      -> "read request" ::: Signal dom Bool+      -> "write request" ::: Signal dom (Maybe (BitVector dataSize))+      -> ( "q"     ::: Signal dom (BitVector dataSize)+         , "full"  ::: Signal dom Bool+         , "empty" ::: Signal dom Bool          )     fifo = Clash.Explicit.Prelude.undefined :}
src/Clash/Prelude.hs view
@@ -1,15 +1,16 @@ {-|   Copyright   :  (C) 2013-2016, University of Twente,-                     2017     , Myrtle Software Ltd, Google Inc.+                     2017-2019, Myrtle Software Ltd+                     2017     , Google Inc.   License     :  BSD2 (see the file LICENSE)   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -  CλaSH (pronounced ‘clash’) is a functional hardware description language that-  borrows both its syntax and semantics from the functional programming language-  Haskell. The merits of using a functional language to describe hardware comes-  from the fact that combinational circuits can be directly modeled as-  mathematical functions and that functional languages lend themselves very well-  at describing and (de-)composing mathematical functions.+  Clash is a functional hardware description language that borrows both its+  syntax and semantics from the functional programming language Haskell. The+  merits of using a functional language to describe hardware comes from the fact+  that combinational circuits can be directly modeled as mathematical functions+  and that functional languages lend themselves very well at describing and+  (de-)composing mathematical functions.    This package provides: @@ -31,14 +32,15 @@   Some circuit examples can be found in "Clash.Examples". -} -{-# LANGUAGE CPP              #-}-{-# LANGUAGE DataKinds        #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeOperators    #-}+{-# LANGUAGE CPP               #-}+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeOperators     #-}  {-# LANGUAGE Unsafe #-} -{-# OPTIONS_HADDOCK show-extensions #-}+{-# OPTIONS_HADDOCK show-extensions, not-home #-}  module Clash.Prelude   ( -- * Creating synchronous sequential circuits@@ -48,12 +50,17 @@   , moore   , mooreB   , registerB+#ifdef CLASH_MULTIPLE_HIDDEN+    -- * Synchronizer circuits for safe clock domain crossings+  , dualFlipFlopSynchronizer+  , asyncFIFOSynchronizer+#endif     -- * ROMs   , asyncRom   , asyncRomPow2   , rom   , romPow2-    -- ** ROMs initialised with a data file+    -- ** ROMs initialized with a data file   , asyncRomFile   , asyncRomFilePow2   , romFile@@ -64,7 +71,10 @@     -- * BlockRAM primitives   , blockRam   , blockRamPow2-    -- ** BlockRAM primitives initialised with a data file+  , blockRamU+  , blockRam1+  , E.ResetStrategy(..)+    -- ** BlockRAM primitives initialized with a data file   , blockRamFile   , blockRamFilePow2     -- ** BlockRAM read/write conflict resolution@@ -76,6 +86,15 @@   , isFalling   , riseEvery   , oscillate+    -- * Tracing+    -- ** Simple+  , traceSignal1+  , traceVecSignal1+    -- ** Tracing in a multi-clock environment+  , traceSignal+  , traceVecSignal+    -- ** VCD dump functions+  , dumpVCD     -- * Exported modules     -- ** Synchronous signals   , module Clash.Signal@@ -99,6 +118,9 @@   , module Clash.Sized.RTree     -- ** Annotations   , module Clash.Annotations.TopEntity+    -- ** Generics type-classes+  , Generic+  , Generic1     -- ** Type-level natural numbers   , module GHC.TypeLits   , module GHC.TypeLits.Extra@@ -112,12 +134,13 @@     -- ** Type classes     -- *** Clash   , module Clash.Class.BitPack+  , module Clash.Class.Exp   , module Clash.Class.Num   , module Clash.Class.Resize     -- *** Other   , module Control.Applicative   , module Data.Bits-  , module Data.Default+  , module Data.Default.Class     -- ** Exceptions   , module Clash.XException   , undefined@@ -125,36 +148,41 @@   , module Clash.NamedTypes     -- ** Hidden arguments   , module Clash.Hidden+    -- ** Magic+  , module Clash.Magic     -- ** Haskell Prelude     -- $hiding-  , module Prelude+  , module Clash.HaskellPrelude   ) where  import           Control.Applicative import           Data.Bits-import           Data.Default+import           Data.Default.Class import           GHC.TypeLits import           GHC.TypeLits.Extra import           Language.Haskell.TH.Syntax  (Lift(..))-import           Prelude hiding-  ((++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate,-   last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt, tail,-   take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined)+import           Clash.HaskellPrelude  import           Clash.Annotations.TopEntity import           Clash.Class.BitPack+import           Clash.Class.Exp import           Clash.Class.Num import           Clash.Class.Resize import qualified Clash.Explicit.Prelude      as E import           Clash.Hidden+import           Clash.Magic import           Clash.NamedTypes import           Clash.Prelude.BitIndex import           Clash.Prelude.BitReduction+import           Clash.Prelude.BlockRam import           Clash.Prelude.BlockRam.File import           Clash.Prelude.DataFlow import           Clash.Prelude.ROM.File import           Clash.Prelude.Safe+#ifdef CLASH_MULTIPLE_HIDDEN+import           Clash.Prelude.Synchronizer+#endif import           Clash.Promoted.Nat import           Clash.Promoted.Nat.TH import           Clash.Promoted.Nat.Literals@@ -168,12 +196,13 @@ import           Clash.Sized.Vector import           Clash.Signal import           Clash.Signal.Delayed+import           Clash.Signal.Trace import           Clash.XException  {- $setup->>> :set -XDataKinds -XFlexibleContexts->>> let window4  = window  :: HiddenClockReset domain gated synchronous => Signal domain Int -> Vec 4 (Signal domain Int)->>> let windowD3 = windowD :: HiddenClockReset domain gated synchronous => Signal domain Int -> Vec 3 (Signal domain Int)+>>> :set -XDataKinds -XFlexibleContexts -XTypeApplications+>>> let window4  = window  :: HiddenClockResetEnable dom  => Signal dom Int -> Vec 4 (Signal dom Int)+>>> let windowD3 = windowD :: HiddenClockResetEnable dom  => Signal dom Int -> Vec 3 (Signal dom Int) -}  {- $hiding@@ -189,32 +218,44 @@  -- | Give a window over a 'Signal' ----- > window4 :: HiddenClockReset domain gated synchronous--- >         => Signal domain Int -> Vec 4 (Signal domain Int)+-- > window4 :: HiddenClockResetEnable dom+-- >         => Signal dom Int -> Vec 4 (Signal dom Int) -- > window4 = window ----- >>> simulateB window4 [1::Int,2,3,4,5] :: [Vec 4 Int]+-- >>> simulateB @System window4 [1::Int,2,3,4,5] :: [Vec 4 Int] -- [<1,0,0,0>,<2,1,0,0>,<3,2,1,0>,<4,3,2,1>,<5,4,3,2>... -- ... window-  :: (KnownNat n, Default a, HiddenClockReset domain gated synchronous)-  => Signal domain a                -- ^ Signal to create a window over-  -> Vec (n + 1) (Signal domain a)  -- ^ Window of at least size 1-window = hideClockReset E.window+  :: ( HiddenClockResetEnable dom+     , KnownNat n+     , Default a+     , NFDataX a )+  => Signal dom a+  -- ^ Signal to create a window over+  -> Vec (n + 1) (Signal dom a)+  -- ^ Window of at least size 1+window = hideClockResetEnable E.window {-# INLINE window #-}  -- | Give a delayed window over a 'Signal' ----- > windowD3 :: HiddenClockReset domain gated synchronous--- >          => Signal domain Int -> Vec 3 (Signal domain Int)+-- > windowD3+-- >   :: HiddenClockResetEnable dom+-- >   => Signal dom Int+-- >   -> Vec 3 (Signal dom Int) -- > windowD3 = windowD ----- >>> simulateB windowD3 [1::Int,2,3,4] :: [Vec 3 Int]+-- >>> simulateB @System windowD3 [1::Int,2,3,4] :: [Vec 3 Int] -- [<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>... -- ... windowD-  :: (KnownNat n, Default a, HiddenClockReset domain gated synchronous)-  => Signal domain a               -- ^ Signal to create a window over-  -> Vec (n + 1) (Signal domain a) -- ^ Window of at least size 1-windowD = hideClockReset E.windowD+  :: ( HiddenClockResetEnable dom+     , KnownNat n+     , Default a+     , NFDataX a )+  => Signal dom a+  -- ^ Signal to create a window over+  -> Vec (n + 1) (Signal dom a)+  -- ^ Window of at least size 1+windowD = hideClockResetEnable E.windowD {-# INLINE windowD #-}
src/Clash/Prelude/BitReduction.hs view
@@ -34,6 +34,11 @@ -- 11_1111 -- >>> reduceAnd (-1 :: Signed 6) -- 1+--+-- Zero width types will evaluate to '1':+--+-- >>> reduceAnd (0 :: Unsigned 0)+-- 1 reduceAnd :: (BitPack a, KnownNat (BitSize a)) => a -> Bit reduceAnd v = reduceAnd# (pack v) @@ -48,7 +53,12 @@ -- 00_0000 -- >>> reduceOr (0 :: Signed 6) -- 0-reduceOr :: BitPack a => a -> Bit+--+-- Zero width types will evaluate to '0':+--+-- >>> reduceOr (0 :: Unsigned 0)+-- 0+reduceOr :: (BitPack a, KnownNat (BitSize a)) => a -> Bit reduceOr v = reduceOr# (pack v)  {-# INLINE reduceXor #-}@@ -66,5 +76,10 @@ -- 11_1011 -- >>> reduceXor (-5 :: Signed 6) -- 1-reduceXor :: BitPack a => a -> Bit+--+-- Zero width types will evaluate to '0':+--+-- >>> reduceXor (0 :: Unsigned 0)+-- 0+reduceXor :: (BitPack a, KnownNat (BitSize a)) => a -> Bit reduceXor v = reduceXor# (pack v)
src/Clash/Prelude/BlockRam.hs view
@@ -1,6 +1,6 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2016-2017, Myrtle Software Ltd,+                  2016-2019, Myrtle Software Ltd,                   2017     , Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>@@ -12,13 +12,13 @@ We will show a rather elaborate example on how you can, and why you might want to use 'blockRam's. We will build a \"small\" CPU+Memory+Program ROM where we will slowly evolve to using blockRams. Note that the code is /not/ meant as a-de-facto standard on how to do CPU design in CλaSH.+de-facto standard on how to do CPU design in Clash.  We start with the definition of the Instructions, Register names and machine codes:  @-{\-\# LANGUAGE RecordWildCards, TupleSections \#-\}+{\-\# LANGUAGE RecordWildCards, TupleSections, DeriveAnyClass, TypeApplications \#-\} module CPU where  import Clash.Prelude@@ -34,7 +34,7 @@   | Load MemAddr Reg   | Store Reg MemAddr   | Nop-  deriving (Eq,Show)+  deriving (Eq, Show)  data Reg   = Zero@@ -44,10 +44,10 @@   | RegC   | RegD   | RegE-  deriving (Eq,Show,Enum)+  deriving (Eq, Show, Enum, Generic, NFDataX)  data Operator = Add | Sub | Incr | Imm | CmpGt-  deriving (Eq,Show)+  deriving (Eq, Show)  data MachCode   = MachCode@@ -61,10 +61,17 @@   , jmpM    :: Maybe Value   } -nullCode = MachCode { inputX = Zero, inputY = Zero, result = Zero, aluCode = Imm-                    , ldReg = Zero, rdAddr = 0, wrAddrM = Nothing-                    , jmpM = Nothing-                    }+nullCode =+  MachCode+    { inputX = Zero+    , inputY = Zero+    , result = Zero+    , aluCode = Imm+    , ldReg = Zero+    , rdAddr = 0+    , wrAddrM = Nothing+    , jmpM = Nothing+    } @  Next we define the CPU and its ALU:@@ -75,36 +82,38 @@     -> ( Vec 7 Value        , (MemAddr, Maybe (MemAddr,Value), InstrAddr)        )-cpu regbank (memOut,instr) = (regbank',(rdAddr,(,aluOut) '<$>' wrAddrM,fromIntegral ipntr))-  where-    -- Current instruction pointer-    ipntr = regbank '!!' PC+cpu regbank (memOut, instr) =+  (regbank', (rdAddr, (,aluOut) '<$>' wrAddrM, fromIntegral ipntr))+ where+  -- Current instruction pointer+  ipntr = regbank '!!' PC -    -- Decoder-    (MachCode {..}) = case instr of-      Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}-      Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}-      Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}-      Load a r             -> nullCode {ldReg=r,rdAddr=a}-      Store r a            -> nullCode {inputX=r,wrAddrM=Just a}-      Nop                  -> nullCode+  -- Decoder+  (MachCode {..}) = case instr of+    Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}+    Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}+    Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}+    Load a r             -> nullCode {ldReg=r,rdAddr=a}+    Store r a            -> nullCode {inputX=r,wrAddrM=Just a}+    Nop                  -> nullCode -    -- ALU-    regX   = regbank '!!' inputX-    regY   = regbank '!!' inputY-    aluOut = alu aluCode regX regY+  -- ALU+  regX   = regbank '!!' inputX+  regY   = regbank '!!' inputY+  aluOut = alu aluCode regX regY -    -- next instruction-    nextPC = case jmpM of-               Just a | aluOut /= 0 -> ipntr + a-               _                    -> ipntr + 1+  -- next instruction+  nextPC =+    case jmpM of+      Just a | aluOut /= 0 -> ipntr + a+      _                    -> ipntr + 1 -    -- update registers-    regbank' = 'replace' Zero   0-             $ 'replace' PC     nextPC-             $ 'replace' result aluOut-             $ 'replace' ldReg  memOut-             $ regbank+  -- update registers+  regbank' = 'replace' Zero   0+           $ 'replace' PC     nextPC+           $ 'replace' result aluOut+           $ 'replace' ldReg  memOut+           $ regbank  alu Add   x y = x + y alu Sub   x y = x - y@@ -116,28 +125,39 @@ We initially create a memory out of simple registers:  @-dataMem :: HiddenClockReset domain gated synchronous-        => Signal domain MemAddr                 -- ^ Read address-        -> Signal domain (Maybe (MemAddr,Value)) -- ^ (write address, data in)-        -> Signal domain Value                   -- ^ data out-dataMem rd wrM = 'Clash.Prelude.Mealy.mealy' dataMemT ('replicate' d32 0) (bundle (rd,wrM))-  where-    dataMemT mem (rd,wrM) = (mem',dout)-      where-        dout = mem '!!' rd-        mem' = case wrM of-                 Just (wr,din) -> 'replace' wr din mem-                 _ -> mem+dataMem+  :: HiddenClockResetEnable dom+  => Signal dom MemAddr+  -- ^ Read address+  -> Signal dom (Maybe (MemAddr,Value))+  -- ^ (write address, data in)+  -> Signal dom Value+  -- ^ data out+dataMem rd wrM =+  'Clash.Prelude.Mealy.mealy' dataMemT ('replicate' d32 0) (bundle (rd,wrM))+ where+  dataMemT mem (rd,wrM) = (mem',dout)+    where+      dout = mem '!!' rd+      mem' =+        case wrM of+          Just (wr,din) -> 'replace' wr din mem+          _             -> mem @  And then connect everything:  @-system :: (KnownNat n, HiddenClockReset domain gated synchronous) => Vec n Instruction -> Signal domain Value+system+  :: ( KnownNat n+     , HiddenClockResetEnable dom+     )+  => Vec n Instruction+  -> Signal dom Value system instrs = memOut   where     memOut = dataMem rdAddr dout-    (rdAddr,dout,ipntr) = 'Clash.Prelude.Mealy.mealyB' cpu ('replicate' d7 0) (memOut,instr)+    (rdAddr, dout, ipntr) = 'Clash.Prelude.Mealy.mealyB' cpu ('replicate' d7 0) (memOut,instr)     instr  = 'Clash.Prelude.ROM.asyncRom' instrs '<$>' ipntr @ @@ -178,8 +198,8 @@ And test our system:  @->>> sampleN 31 (system prog)-[0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> sampleN @System 32 (system prog)+[0,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -195,7 +215,11 @@ has the potential to be translated to a more efficient structure:  @-system2 :: (KnownNat n, HiddenClockReset domain gated synchronous) => Vec n Instruction -> Signal domain Value+system2+  :: ( KnownNat n+     , HiddenClockResetEnable dom  )+  => Vec n Instruction+  -> Signal dom Value system2 instrs = memOut   where     memOut = 'Clash.Prelude.RAM.asyncRam' d32 rdAddr dout@@ -210,8 +234,8 @@ filter out the undefinedness and replace it with the string "X" in the few leading outputs.  @->>> printX $ sampleN 31 (system2 prog)-[X,X,X,X,X,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> printX $ sampleN @System 32 (system2 prog)+[X,X,X,X,X,X,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -224,7 +248,7 @@ 'blockRam' function will be translated to such a /Block RAM/.  One important aspect of Block RAMs have a /synchronous/ read port, meaning that,-unlike the behaviour of 'Clash.Prelude.RAM.asyncRam', given a read address @r@+unlike the behavior of 'Clash.Prelude.RAM.asyncRam', given a read address @r@ at time @t@, the value @v@ in the RAM at address @r@ is only available at time @t+1@. @@ -236,48 +260,57 @@ is loaded:  @-cpu2 :: (Vec 7 Value,Reg)    -- ^ (Register bank, Load reg addr)-     -> (Value,Instruction)  -- ^ (Memory output, Current instruction)-     -> ( (Vec 7 Value,Reg)-        , (MemAddr, Maybe (MemAddr,Value), InstrAddr)-        )-cpu2 (regbank,ldRegD) (memOut,instr) = ((regbank',ldRegD'),(rdAddr,(,aluOut) '<$>' wrAddrM,fromIntegral ipntr))-  where-    -- Current instruction pointer-    ipntr = regbank '!!' PC+cpu2+  :: (Vec 7 Value,Reg)+  -- ^ (Register bank, Load reg addr)+  -> (Value, Instruction)+  -- ^ (Memory output, Current instruction)+  -> ( (Vec 7 Value,Reg)+     , (MemAddr, Maybe (MemAddr, Value), InstrAddr)+     )+cpu2 (regbank,ldRegD) (memOut,instr) =+  ((regbank', ldRegD'), (rdAddr, (,aluOut) '<$>' wrAddrM, fromIntegral ipntr))+ where+  -- Current instruction pointer+  ipntr = regbank '!!' PC -    -- Decoder-    (MachCode {..}) = case instr of-      Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}-      Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}-      Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}-      Load a r             -> nullCode {ldReg=r,rdAddr=a}-      Store r a            -> nullCode {inputX=r,wrAddrM=Just a}-      Nop                  -> nullCode+  -- Decoder+  (MachCode {..}) = case instr of+    Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}+    Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}+    Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}+    Load a r             -> nullCode {ldReg=r,rdAddr=a}+    Store r a            -> nullCode {inputX=r,wrAddrM=Just a}+    Nop                  -> nullCode -    -- ALU-    regX   = regbank '!!' inputX-    regY   = regbank '!!' inputY-    aluOut = alu aluCode regX regY+  -- ALU+  regX   = regbank '!!' inputX+  regY   = regbank '!!' inputY+  aluOut = alu aluCode regX regY -    -- next instruction-    nextPC = case jmpM of-               Just a | aluOut /= 0 -> ipntr + a-               _                    -> ipntr + 1+  -- next instruction+  nextPC =+    case jmpM of+      Just a | aluOut /= 0 -> ipntr + a+      _                    -> ipntr + 1 -    -- update registers-    ldRegD'  = ldReg -- Delay the ldReg by 1 cycle-    regbank' = 'replace' Zero   0-             $ 'replace' PC     nextPC-             $ 'replace' result aluOut-             $ 'replace' ldRegD memOut-             $ regbank+  -- update registers+  ldRegD'  = ldReg  -- Delay the ldReg by 1 cycle+  regbank' = 'replace' Zero   0+           $ 'replace' PC     nextPC+           $ 'replace' result aluOut+           $ 'replace' ldRegD memOut+           $ regbank @  We can now finally instantiate our system with a 'blockRam':  @-system3 :: (KnownNat n, HiddenClockReset domain gated synchronous) => Vec n Instruction -> Signal domain Value+system3+  :: (KnownNat n+     , HiddenClockResetEnable dom  )+  => Vec n Instruction+  -> Signal dom Value system3 instrs = memOut   where     memOut = 'blockRam' (replicate d32 0) rdAddr dout@@ -330,8 +363,8 @@ filter out the undefinedness and replace it with the string "X".  @->>> printX $ sampleN 33 (system3 prog2)-[X,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+>>> printX $ sampleN @System 34 (system3 prog2)+[X,0,0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]  @ @@ -339,11 +372,9 @@  -} -{-# LANGUAGE BangPatterns        #-} {-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleContexts    #-} {-# LANGUAGE GADTs               #-}-{-# LANGUAGE MagicHash           #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators       #-} @@ -352,26 +383,33 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Prelude.BlockRam-  ( -- * BlockRAM synchronised to the system clock+  ( -- * BlockRAM synchronized to the system clock     blockRam   , blockRamPow2+  , blockRamU+  , blockRam1+  , E.ResetStrategy(..)     -- * Read/Write conflict resolution   , readNew   ) where -import           GHC.TypeLits            (KnownNat, type (^))+import           GHC.TypeLits            (KnownNat, type (^), type (<=)) import           GHC.Stack               (HasCallStack, withFrozenCallStack)  import qualified Clash.Explicit.BlockRam as E+import           Clash.Promoted.Nat      (SNat) import           Clash.Signal+import           Clash.Sized.Index       (Index) import           Clash.Sized.Unsigned    (Unsigned) import           Clash.Sized.Vector      (Vec)+import           Clash.XException        (NFDataX)  {- $setup >>> import Clash.Prelude as C >>> import qualified Data.List as L >>> :set -XDataKinds -XRecordWildCards -XTupleSections -XTypeApplications -XFlexibleContexts+>>> :set -XDeriveAnyClass -XDeriveGeneric >>> type InstrAddr = Unsigned 8 >>> type MemAddr = Unsigned 5 >>> type Value = Signed 8@@ -384,7 +422,7 @@   | RegC   | RegD   | RegE-  deriving (Eq,Show,Enum)+  deriving (Eq,Show,Enum,C.Generic,NFDataX) :}  >>> :{@@ -468,10 +506,10 @@  >>> :{ dataMem-  :: HiddenClockReset domain gated synchronous-  => Signal domain MemAddr-  -> Signal domain (Maybe (MemAddr,Value))-  -> Signal domain Value+  :: HiddenClockResetEnable dom+  => Signal dom MemAddr+  -> Signal dom (Maybe (MemAddr,Value))+  -> Signal dom Value dataMem rd wrM = mealy dataMemT (C.replicate d32 0) (bundle (rd,wrM))   where     dataMemT mem (rd,wrM) = (mem',dout)@@ -484,9 +522,9 @@  >>> :{ system-  :: (KnownNat n, HiddenClockReset domain gated synchronous)+  :: (KnownNat n, HiddenClockResetEnable dom )   => Vec n Instruction-  -> Signal domain Value+  -> Signal dom Value system instrs = memOut   where     memOut = dataMem rdAddr dout@@ -528,9 +566,10 @@  >>> :{ system2-  :: (KnownNat n, HiddenClockReset domain gated synchronous)+  :: ( KnownNat n+     , HiddenClockResetEnable dom  )   => Vec n Instruction-  -> Signal domain Value+  -> Signal dom Value system2 instrs = memOut   where     memOut = asyncRam d32 rdAddr dout@@ -539,45 +578,51 @@ :}  >>> :{-cpu2 :: (Vec 7 Value,Reg)    -- ^ (Register bank, Load reg addr)-     -> (Value,Instruction)  -- ^ (Memory output, Current instruction)-     -> ( (Vec 7 Value,Reg)-        , (MemAddr,Maybe (MemAddr,Value),InstrAddr)-        )-cpu2 (regbank,ldRegD) (memOut,instr) = ((regbank',ldRegD'),(rdAddr,(,aluOut) <$> wrAddrM,fromIntegral ipntr))-  where-    -- Current instruction pointer-    ipntr = regbank C.!! PC-    -- Decoder-    (MachCode {..}) = case instr of-      Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}-      Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}-      Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}-      Load a r             -> nullCode {ldReg=r,rdAddr=a}-      Store r a            -> nullCode {inputX=r,wrAddrM=Just a}-      Nop                  -> nullCode-    -- ALU-    regX   = regbank C.!! inputX-    regY   = regbank C.!! inputY-    aluOut = alu aluCode regX regY-    -- next instruction-    nextPC = case jmpM of-               Just a | aluOut /= 0 -> ipntr + a-               _                    -> ipntr + 1-    -- update registers-    ldRegD'  = ldReg -- Delay the ldReg by 1 cycle-    regbank' = replace Zero   0-             $ replace PC     nextPC-             $ replace result aluOut-             $ replace ldRegD memOut-             $ regbank+cpu2+  :: (Vec 7 Value,Reg)+  -- ^ (Register bank, Load reg addr)+  -> (Value,Instruction)+  -- ^ (Memory output, Current instruction)+  -> ( (Vec 7 Value,Reg)+     , (MemAddr, Maybe (MemAddr, Value), InstrAddr)+     )+cpu2 (regbank,ldRegD) (memOut,instr) =+  ((regbank', ldRegD'), (rdAddr, (,aluOut) <$> wrAddrM, fromIntegral ipntr))+ where+  -- Current instruction pointer+  ipntr = regbank C.!! PC+  -- Decoder+  (MachCode {..}) = case instr of+    Compute op rx ry res -> nullCode {inputX=rx,inputY=ry,result=res,aluCode=op}+    Branch cr a          -> nullCode {inputX=cr,jmpM=Just a}+    Jump a               -> nullCode {aluCode=Incr,jmpM=Just a}+    Load a r             -> nullCode {ldReg=r,rdAddr=a}+    Store r a            -> nullCode {inputX=r,wrAddrM=Just a}+    Nop                  -> nullCode+  -- ALU+  regX   = regbank C.!! inputX+  regY   = regbank C.!! inputY+  aluOut = alu aluCode regX regY+  -- next instruction+  nextPC =+    case jmpM of+      Just a | aluOut /= 0 -> ipntr + a+      _                    -> ipntr + 1+  -- update registers+  ldRegD'  = ldReg -- Delay the ldReg by 1 cycle+  regbank' = replace Zero   0+           $ replace PC     nextPC+           $ replace result aluOut+           $ replace ldRegD memOut+           $ regbank :}  >>> :{ system3-  :: (KnownNat n, HiddenClockReset domain gated synchronous)+  :: ( KnownNat n+     , HiddenClockResetEnable dom  )   => Vec n Instruction-  -> Signal domain Value+  -> Signal dom Value system3 instrs = memOut   where     memOut = blockRam (C.replicate d32 0) rdAddr dout@@ -626,10 +671,10 @@ -- -- @ -- bram40---   :: 'HiddenClock' domain---   => 'Signal' domain ('Unsigned' 6)---   -> 'Signal' domain (Maybe ('Unsigned' 6, 'Clash.Sized.BitVector.Bit'))---   -> 'Signal' domain 'Clash.Sized.BitVector.Bit'+--   :: 'HiddenClock' dom+--   => 'Signal' dom ('Unsigned' 6)+--   -> 'Signal' dom (Maybe ('Unsigned' 6, 'Clash.Sized.BitVector.Bit'))+--   -> 'Signal' dom 'Clash.Sized.BitVector.Bit' -- bram40 = 'blockRam' ('Clash.Sized.Vector.replicate' d40 1) -- @ --@@ -639,21 +684,83 @@ -- Block RAM. -- * Use the adapter 'readNew' for obtaining write-before-read semantics like this: @readNew (blockRam inits) rd wrM@. blockRam-  :: (Enum addr, HiddenClock domain gated, HasCallStack)-  => Vec n a     -- ^ Initial content of the BRAM, also-                 -- determines the size, @n@, of the BRAM.-                 ---                 -- __NB__: __MUST__ be a constant.-  -> Signal domain addr -- ^ Read address @r@-  -> Signal domain (Maybe (addr, a))+  :: ( HasCallStack+     , HiddenClock dom+     , HiddenEnable dom+     , NFDataX a+     , Enum addr+     )+  => Vec n a+  -- ^ Initial content of the BRAM, also determines the size, @n@, of the BRAM.+  --+  -- __NB__: __MUST__ be a constant.+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))    -- ^ (write address @w@, value to write)-  -> Signal domain a+  -> Signal dom a   -- ^ Value of the @blockRAM@ at address @r@ from the previous clock   -- cycle blockRam = \cnt rd wrM -> withFrozenCallStack-  (hideClock E.blockRam cnt rd wrM)+  (hideEnable (hideClock E.blockRam) cnt rd wrM) {-# INLINE blockRam #-} +-- | Version of blockram that has no default values set. May be cleared to a+-- arbitrary state using a reset function.+blockRamU+   :: forall n dom a r addr+   . ( HasCallStack+     , HiddenClockResetEnable dom+     , NFDataX a+     , Enum addr+     , 1 <= n )+  => E.ResetStrategy r+  -- ^ Whether to clear BRAM on asserted reset ('ClearOnReset') or+  -- not ('NoClearOnReset'). Reset needs to be asserted at least /n/ cycles to+  -- clear the BRAM.+  -> SNat n+  -- ^ Number of elements in BRAM+  -> (Index n -> a)+  -- ^ If applicable (see first argument), reset BRAM using this function.+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))+  -- ^ (write address @w@, value to write)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRamU =+  \rstStrategy cnt initF rd wrM -> withFrozenCallStack+    (hideClockResetEnable E.blockRamU) rstStrategy cnt initF rd wrM+{-# INLINE blockRamU #-}++-- | Version of blockram that is initialized with the same value on all+-- memory positions.+blockRam1+   :: forall n dom a r addr+   . ( HasCallStack+     , HiddenClockResetEnable dom+     , NFDataX a+     , Enum addr+     , 1 <= n )+  => E.ResetStrategy r+  -- ^ Whether to clear BRAM on asserted reset ('ClearOnReset') or+  -- not ('NoClearOnReset'). Reset needs to be asserted at least /n/ cycles to+  -- clear the BRAM.+  -> SNat n+  -- ^ Number of elements in BRAM+  -> a+  -- ^ Initial content of the BRAM (replicated /n/ times)+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))+  -- ^ (write address @w@, value to write)+  -> Signal dom a+  -- ^ Value of the @blockRAM@ at address @r@ from the previous clock cycle+blockRam1 =+  \rstStrategy cnt initValue rd wrM -> withFrozenCallStack+    (hideClockResetEnable E.blockRam1) rstStrategy cnt initValue rd wrM+{-# INLINE blockRam1 #-}+ -- | Create a blockRAM with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle@@ -661,10 +768,10 @@ -- -- @ -- bram32---   :: 'HiddenClock' domain---   => 'Signal' domain ('Unsigned' 5)---   -> 'Signal' domain (Maybe ('Unsigned' 5, 'Clash.Sized.BitVector.Bit'))---   -> 'Signal' domain 'Clash.Sized.BitVector.Bit'+--   :: 'HiddenClock' dom+--   => 'Signal' dom ('Unsigned' 5)+--   -> 'Signal' dom (Maybe ('Unsigned' 5, 'Clash.Sized.BitVector.Bit'))+--   -> 'Signal' dom 'Clash.Sized.BitVector.Bit' -- bram32 = 'blockRamPow2' ('Clash.Sized.Vector.replicate' d32 1) -- @ --@@ -674,37 +781,49 @@ -- Block RAM. -- * Use the adapter 'readNew' for obtaining write-before-read semantics like this: @readNew (blockRamPow2 inits) rd wrM@. blockRamPow2-  :: (KnownNat n, HiddenClock domain gated, HasCallStack)-  => Vec (2^n) a         -- ^ Initial content of the BRAM, also-                         -- determines the size, @2^n@, of the BRAM.-                         ---                         -- __NB__: __MUST__ be a constant.-  -> Signal domain (Unsigned n) -- ^ Read address @r@-  -> Signal domain (Maybe (Unsigned n, a))+  :: ( HasCallStack+     , HiddenClock dom+     , HiddenEnable dom+     , NFDataX a+     , KnownNat n+     )+  => Vec (2^n) a+  -- ^ Initial content of the BRAM, also determines the size, @2^n@, of the BRAM.+  --+  -- __NB__: __MUST__ be a constant.+  -> Signal dom (Unsigned n)+  -- ^ Read address @r@+  -> Signal dom (Maybe (Unsigned n, a))   -- ^ (write address @w@, value to write)-  -> Signal domain a+  -> Signal dom a   -- ^ Value of the @blockRAM@ at address @r@ from the previous clock   -- cycle blockRamPow2 = \cnt rd wrM -> withFrozenCallStack-  (hideClock E.blockRamPow2 cnt rd wrM)+  (hideEnable (hideClock E.blockRamPow2) cnt rd wrM) {-# INLINE blockRamPow2 #-} --- | Create read-after-write blockRAM from a read-before-write one (synchronised to system clock)+-- | Create read-after-write blockRAM from a read-before-write one (synchronized to system clock) -- -- >>> import Clash.Prelude -- >>> :t readNew (blockRam (0 :> 1 :> Nil)) -- readNew (blockRam (0 :> 1 :> Nil)) --   :: ...+--      ...+--      ...+--      ... --      ... =>---      Signal domain addr---      -> Signal domain (Maybe (addr, a)) -> Signal domain a-readNew :: (Eq addr, HiddenClockReset domain gated synchronous)-        => (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a)-        -- ^ The @ram@ component-        -> Signal domain addr              -- ^ Read address @r@-        -> Signal domain (Maybe (addr, a)) -- ^ (Write address @w@, value to write)-        -> Signal domain a-        -- ^ Value of the @ram@ at address @r@ from the previous clock-        -- cycle-readNew = hideClockReset (\clk rst -> E.readNew rst clk)+--      Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a+readNew+  :: ( HiddenClockResetEnable dom+     , NFDataX a+     , Eq addr )+  => (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a)+  -- ^ The @ram@ component+  -> Signal dom addr+  -- ^ Read address @r@+  -> Signal dom (Maybe (addr, a))+  -- ^ (Write address @w@, value to write)+  -> Signal dom a+  -- ^ Value of the @ram@ at address @r@ from the previous clock cycle+readNew = hideClockResetEnable E.readNew {-# INLINE readNew #-}
src/Clash/Prelude/BlockRam/File.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2019     , Myrtle Software Ltd+                  2017     , Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -= Initialising a BlockRAM with a data file #usingramfiles#+= Initializing a BlockRAM with a data file #usingramfiles# -BlockRAM primitives that can be initialised with a data file. The BNF grammar+BlockRAM primitives that can be initialized with a data file. The BNF grammar for this data file is simple:  @@@ -33,8 +34,8 @@ We can instantiate a BlockRAM using the content of the above file like so:  @-f :: HiddenClock domain -> Signal domain (Unsigned 3) -> Signal domain (Unsigned 9)-f rd = 'Clash.Class.BitPack.unpack' '<$>' exposeClock 'blockRamFile' clk d7 \"memory.bin\" rd (signal Nothing)+f :: HiddenClock dom  -> Signal dom (Unsigned 3) -> Signal dom (Unsigned 9)+f rd = 'Clash.Class.BitPack.unpack' '<$>' exposeClock 'blockRamFile' clk d7 \"memory.bin\" rd (pure Nothing) @  In the example above, we basically treat the BlockRAM as an synchronous ROM.@@ -50,8 +51,8 @@ number, and a 3-bit signed number:  @-g :: HiddenClock domain -> Signal domain (Unsigned 3) -> Signal domain (Unsigned 6,Signed 3)-g clk rd = 'Clash.Class.BitPack.unpack' '<$>' exposeClock 'blockRamFile' clk d7 \"memory.bin\" rd (signal Nothing)+g :: HiddenClock dom  -> Signal dom (Unsigned 3) -> Signal dom (Unsigned 6,Signed 3)+g clk rd = 'Clash.Class.BitPack.unpack' '<$>' exposeClock 'blockRamFile' clk d7 \"memory.bin\" rd (pure Nothing) @  And then we would see:@@ -78,7 +79,7 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Prelude.BlockRam.File-  ( -- * BlockRAM synchronised to an arbitrary clock+  ( -- * BlockRAM synchronized to an arbitrary clock     blockRamFile   , blockRamFilePow2   )@@ -90,7 +91,8 @@  import qualified Clash.Explicit.BlockRam.File as E import           Clash.Promoted.Nat           (SNat)-import           Clash.Signal                 (HiddenClock, Signal, hideClock)+import           Clash.Signal+  (HiddenClock, HiddenEnable, Signal, hideClock, hideEnable) import           Clash.Sized.BitVector        (BitVector) import           Clash.Sized.Unsigned         (Unsigned) @@ -115,25 +117,29 @@ -- -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- Block RAM.--- * Use the adapter 'readNew'' for obtaining write-before-read semantics like this: @readNew' clk (blockRamFilePow2' clk file) rd wrM@.+-- * Use the adapter 'Clash.Prelude.BlockRam.readNew' for obtaining write-before-read semantics like this: @'Clash.Prelude.BlockRam.readNew' clk ('blockRamFilePow2' clk file) rd wrM@. -- * See "Clash.Prelude.BlockRam.File#usingramfiles" for more information on how -- to instantiate a Block RAM with the contents of a data file. -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. blockRamFilePow2-  :: forall domain gated n m-   . (KnownNat m, KnownNat n, HiddenClock domain gated, HasCallStack)+  :: forall dom  n m+   . ( KnownNat m+     , KnownNat n+     , HiddenClock dom+     , HiddenEnable dom+     , HasCallStack )   => FilePath   -- ^ File describing the initial content of the blockRAM-  -> Signal domain (Unsigned n)+  -> Signal dom (Unsigned n)   -- ^ Read address @r@-  -> Signal domain (Maybe (Unsigned n, BitVector m))+  -> Signal dom (Maybe (Unsigned n, BitVector m))   -- ^ (write address @w@, value to write)-  -> Signal domain (BitVector m)+  -> Signal dom (BitVector m)   -- ^ Value of the @blockRAM@ at address @r@ from the previous   -- clock cycle blockRamFilePow2 = \fp rd wrM -> withFrozenCallStack-  (hideClock E.blockRamFilePow2 fp rd wrM)+  (hideEnable (hideClock E.blockRamFilePow2) fp rd wrM) {-# INLINE blockRamFilePow2 #-}  -- | Create a blockRAM with space for @n@ elements@@ -157,24 +163,28 @@ -- -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- Block RAM.--- * Use the adapter 'readNew'' for obtaining write-before-read semantics like this: @readNew' clk (blockRamFile' clk size file) rd wrM@.+-- * Use the adapter 'Clash.Prelude.BlockRam.readNew' for obtaining write-before-read semantics like this: @'Clash.Prelude.BlockRam.readNew' clk ('blockRamFile' clk size file) rd wrM@. -- * See "Clash.Prelude.BlockRam.File#usingramfiles" for more information on how -- to instantiate a Block RAM with the contents of a data file. -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. blockRamFile-  :: (KnownNat m, Enum addr, HiddenClock domain gated, HasCallStack)+  :: ( KnownNat m+     , Enum addr+     , HiddenClock dom+     , HiddenEnable dom+     , HasCallStack )   => SNat n   -- ^ Size of the blockRAM   -> FilePath   -- ^ File describing the initial content of the blockRAM-  -> Signal domain addr+  -> Signal dom addr   -- ^ Read address @r@-  -> Signal domain (Maybe (addr, BitVector m))+  -> Signal dom (Maybe (addr, BitVector m))   -- ^ (write address @w@, value to write)-  -> Signal domain (BitVector m)+  -> Signal dom (BitVector m)   -- ^ Value of the @blockRAM@ at address @r@ from the previous   -- clock cycle blockRamFile = \sz fp rd wrM -> withFrozenCallStack-  (hideClock E.blockRamFile sz fp rd wrM)+  (hideEnable (hideClock E.blockRamFile) sz fp rd wrM) {-# INLINE blockRamFile #-}
src/Clash/Prelude/DataFlow.hs view
@@ -1,10 +1,11 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -Self-synchronising circuits based on data-flow principles.+Self-synchronizing circuits based on data-flow principles. -}  {-# LANGUAGE DataKinds             #-}@@ -15,7 +16,7 @@ {-# LANGUAGE TypeFamilies          #-} {-# LANGUAGE TypeOperators         #-} -{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE Safe #-}  {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} {-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise       #-}@@ -46,22 +47,22 @@ where  import GHC.TypeLits           (KnownNat, type (+), type (^))-import Prelude                hiding ((++), (!!), length, map, repeat, tail, unzip3, zip3-                              , zipWith)+import Prelude+  hiding ((++), (!!), length, map, repeat, tail, unzip3, zip3, zipWith)  import Clash.Class.BitPack    (boolToBV) import Clash.Class.Resize     (truncateB) import Clash.Prelude.BitIndex (msb) import Clash.Explicit.Mealy   (mealyB) import Clash.Promoted.Nat     (SNat)-import Clash.Signal           ((.&&.), unbundle)+import Clash.Signal           (KnownDomain, (.&&.)) import Clash.Signal.Bundle    (Bundle (..))-import Clash.Signal.Internal  (clockGate, register#)-import Clash.Explicit.Signal  (Clock, Reset, Signal)+import Clash.Explicit.Signal  (Clock, Reset, Signal, Enable, enable, register) import Clash.Sized.BitVector  (BitVector) import Clash.Sized.Vector+import Clash.XException       (errorX, NFDataX) -{- | Dataflow circuit with bidirectional synchronisation channels.+{- | Dataflow circuit with bidirectional synchronization channels.  In the /forward/ direction we assert /validity/ of the data. In the /backward/ direction we assert that the circuit is /ready/ to receive new data. A circuit@@ -70,26 +71,26 @@  * Not consume data when validity is deasserted.  * Only update its output when readiness is asserted. -The 'DataFlow'' type is defined as:+The 'DataFlow' type is defined as:  @ newtype DataFlow' dom iEn oEn i o   = DF-  { df :: 'Signal'' dom i     -- Incoming data-       -> 'Signal'' dom iEn   -- Flagged with /valid/ bits @iEn@.-       -> 'Signal'' dom oEn   -- Incoming back-pressure, /ready/ edge.-       -> ( 'Signal'' dom o   -- Outgoing data.-          , 'Signal'' dom oEn -- Flagged with /valid/ bits @oEn@.-          , 'Signal'' dom iEn -- Outgoing back-pressure, /ready/ edge.+  { df :: 'Signal' dom i     -- Incoming data+       -> 'Signal' dom iEn   -- Flagged with /valid/ bits @iEn@.+       -> 'Signal' dom oEn   -- Incoming back-pressure, /ready/ edge.+       -> ( 'Signal' dom o   -- Outgoing data.+          , 'Signal' dom oEn -- Flagged with /valid/ bits @oEn@.+          , 'Signal' dom iEn -- Outgoing back-pressure, /ready/ edge.           )   } @  where: - * @dom@ is the clock to which the circuit is synchronised.- * @iEn@ is the type of the bidirectional incoming synchronisation channel.- * @oEn@ is the type of the bidirectional outgoing synchronisation channel.+ * @dom@ is the domain to which the circuit is synchronized.+ * @iEn@ is the type of the bidirectional incoming synchronization channel.+ * @oEn@ is the type of the bidirectional outgoing synchronization channel.  * @i@ is the incoming data type.  * @o@ is the outgoing data type. @@ -101,33 +102,33 @@  * 'lockStep' proceed in lock-step.  When you look at the types of the above operators it becomes clear why we-parametrise in the types of the synchronisation channels.+parametrize in the types of the synchronization channels. -}-newtype DataFlow domain iEn oEn i o+newtype DataFlow dom iEn oEn i o   = DF   { -- | Create an ordinary circuit from a 'DataFlow' circuit-    df :: Signal domain i     -- Incoming data-       -> Signal domain iEn   -- Flagged with /valid/ bits @iEn@.-       -> Signal domain oEn   -- Incoming back-pressure, /ready/ edge.-       -> ( Signal domain o   -- Outgoing data.-          , Signal domain oEn -- Flagged with /valid/ bits @oEn@.-          , Signal domain iEn -- Outgoing back-pressure, /ready/ edge.+    df :: Signal dom i     -- Incoming data+       -> Signal dom iEn   -- Flagged with /valid/ bits @iEn@.+       -> Signal dom oEn   -- Incoming back-pressure, /ready/ edge.+       -> ( Signal dom o   -- Outgoing data.+          , Signal dom oEn -- Flagged with /valid/ bits @oEn@.+          , Signal dom iEn -- Outgoing back-pressure, /ready/ edge.           )   } --- | Dataflow circuit synchronised to the 'systemClockGen'.+-- | Dataflow circuit synchronized to the 'systemClockGen'. -- type DataFlow iEn oEn i o = DataFlow' systemClockGen iEn oEn i o  -- | Create a 'DataFlow' circuit from a circuit description with the appropriate -- type: -- -- @--- 'Signal'' dom i        -- Incoming data.--- -> 'Signal'' dom Bool  -- Flagged with a single /valid/ bit.--- -> 'Signal'' dom Bool  -- Incoming back-pressure, /ready/ bit.--- -> ( 'Signal'' dom o   -- Outgoing data.---    , 'Signal'' dom oEn -- Flagged with a single /valid/ bit.---    , 'Signal'' dom iEn -- Outgoing back-pressure, /ready/ bit.+-- 'Signal' dom i        -- Incoming data.+-- -> 'Signal' dom Bool  -- Flagged with a single /valid/ bit.+-- -> 'Signal' dom Bool  -- Incoming back-pressure, /ready/ bit.+-- -> ( 'Signal' dom o   -- Outgoing data.+--    , 'Signal' dom oEn -- Flagged with a single /valid/ bit.+--    , 'Signal' dom iEn -- Outgoing back-pressure, /ready/ bit. --    ) -- @ --@@ -135,46 +136,60 @@ -- --  * Not consume data when validity is deasserted. --  * Only update its output when readiness is asserted.-liftDF :: (Signal dom i -> Signal dom Bool -> Signal dom Bool-                        -> (Signal dom o, Signal dom Bool, Signal dom Bool))-       -> DataFlow dom Bool Bool i o+liftDF+  :: ( Signal dom i+    -> Signal dom Bool+    -> Signal dom Bool+    -> (Signal dom o, Signal dom Bool, Signal dom Bool))+  -> DataFlow dom Bool Bool i o liftDF = DF  -- | Create a 'DataFlow' circuit where the given function @f@ operates on the--- data, and the synchronisation channels are passed unaltered.-pureDF :: (i -> o)-       -> DataFlow dom Bool Bool i o+-- data, and the synchronization channels are passed unaltered.+pureDF+  :: (i -> o)+  -> DataFlow dom Bool Bool i o pureDF f = DF (\i iV oR -> (fmap f i,iV,oR))  -- | Create a 'DataFlow' circuit from a Mealy machine description as those of -- "Clash.Prelude.Mealy"-mealyDF :: Clock domain gated-        -> Reset domain synchronous-        -> (s -> i -> (s,o))-        -> s-        -> DataFlow domain Bool Bool i o-mealyDF clk rst f iS =+mealyDF+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (s -> i -> (s,o))+  -> s+  -> DataFlow dom Bool Bool i o+mealyDF clk rst gen f iS =   DF (\i iV oR -> let en     = iV .&&. oR                       (s',o) = unbundle (f <$> s <*> i)-                      s      = register# (clockGate clk en) rst iS s'+                      s      = register clk rst (enable gen en) iS s'                   in  (o,iV,oR))  -- | Create a 'DataFlow' circuit from a Moore machine description as those of -- "Clash.Prelude.Moore"-mooreDF :: Clock domain gated-        -> Reset domain synchronous-        -> (s -> i -> s)-        -> (s -> o)-        -> s-        -> DataFlow domain Bool Bool i o-mooreDF clk rst ft fo iS =+mooreDF+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (s -> i -> s)+  -> (s -> o)+  -> s+  -> DataFlow dom Bool Bool i o+mooreDF clk rst gen ft fo iS =   DF (\i iV oR -> let en  = iV .&&. oR                       s'  = ft <$> s <*> i-                      s   = register# (clockGate clk en) rst iS s'+                      s   = register clk rst (enable gen en) iS s'                       o   = fo <$> s                   in  (o,iV,oR)) -fifoDF_mealy :: forall addrSize a . KnownNat addrSize+fifoDF_mealy+  :: forall addrSize a+   . KnownNat addrSize   => (Vec (2^addrSize) a, BitVector (addrSize + 1), BitVector (addrSize + 1))   -> (a, Bool, Bool)   -> ((Vec (2^addrSize) a, BitVector (addrSize + 1), BitVector (addrSize + 1))@@ -202,20 +217,27 @@ -- @ -- fifo4 = 'fifoDF' d4 (2 :> 3 :> Nil) -- @-fifoDF :: forall addrSize m n a domain gated synchronous .-     (KnownNat addrSize, KnownNat n, KnownNat m, (m + n) ~ (2 ^ addrSize))-  => Clock domain gated-  -> Reset domain synchronous+fifoDF+  :: forall addrSize m n a dom+   . ( KnownDomain dom+     , NFDataX a+     , KnownNat addrSize+     , KnownNat n+     , KnownNat m+     , (m + n) ~ (2 ^ addrSize) )+  => Clock dom+  -> Reset dom+  -> Enable dom   -> SNat (m + n) -- ^ Depth of the FIFO buffer. Must be a power of two.   -> Vec m a      -- ^ Initial content. Can be smaller than the size of the-                  -- FIFO. Empty spaces are initialised with 'undefined'.-  -> DataFlow domain Bool Bool a a-fifoDF clk rst _ iS = DF $ \i iV oR ->+                  -- FIFO. Empty spaces are initialized with 'undefined'.+  -> DataFlow dom Bool Bool a a+fifoDF clk rst en _ iS = DF $ \i iV oR ->   let initRdPtr      = 0       initWrPtr      = fromIntegral (length iS)-      initMem        = iS ++ repeat undefined :: Vec (m + n) a+      initMem        = iS ++ repeat  (errorX "fifoDF: undefined") :: Vec (m + n) a       initS          = (initMem,initRdPtr,initWrPtr)-      (o,empty,full) = mealyB clk rst fifoDF_mealy initS (i,iV,oR)+      (o,empty,full) = mealyB clk rst en fifoDF_mealy initS (i,iV,oR)   in  (o,not <$> empty, not <$> full)  -- | Identity circuit@@ -227,9 +249,10 @@ -- | Sequential composition of two 'DataFlow' circuits. -- -- <<doc/seqDF.svg>>-seqDF :: DataFlow dom aEn bEn a b-      -> DataFlow dom bEn cEn b c-      -> DataFlow dom aEn cEn a c+seqDF+  :: DataFlow dom aEn bEn a b+  -> DataFlow dom bEn cEn b c+  -> DataFlow dom aEn cEn a c (DF f) `seqDF` (DF g) = DF (\a aVal cRdy -> let (b,bVal,aRdy) = f a aVal bRdy                                                 (c,cVal,bRdy) = g b bVal cRdy                                             in  (c,cVal,aRdy))@@ -238,8 +261,9 @@ -- the second halve unchanged. -- -- <<doc/firstDF.svg>>-firstDF :: DataFlow dom aEn bEn a b-        -> DataFlow dom (aEn,cEn) (bEn,cEn) (a,c) (b,c)+firstDF+  :: DataFlow dom aEn bEn a b+  -> DataFlow dom (aEn, cEn) (bEn, cEn) (a, c) (b, c) firstDF (DF f) = DF (\ac acV bcR -> let (a,c)     = unbundle ac                                         (aV,cV)   = unbundle acV                                         (bR,cR)   = unbundle bcR@@ -253,7 +277,7 @@ -- | Swap the two communication channels. -- -- <<doc/swapDF.svg>>-swapDF :: DataFlow dom (aEn,bEn) (bEn,aEn) (a,b) (b,a)+swapDF :: DataFlow dom (aEn, bEn) (bEn, aEn) (a, b) (b, a) swapDF = DF (\ab abV baR -> (swap <$> ab, swap <$> abV, swap <$> baR))   where     swap ~(a,b) = (b,a)@@ -262,26 +286,25 @@ -- the first halve unchanged. -- -- <<doc/secondDF.svg>>-secondDF :: DataFlow dom aEn bEn a b-         -> DataFlow dom (cEn,aEn) (cEn,bEn) (c,a) (c,b)+secondDF+  :: DataFlow dom aEn bEn a b+  -> DataFlow dom (cEn, aEn) (cEn, bEn) (c, a) (c, b) secondDF f = swapDF `seqDF` firstDF f `seqDF` swapDF  -- | Compose two 'DataFlow' circuits in parallel. -- -- <<doc/parDF.svg>>-parDF :: DataFlow dom aEn bEn a b-      -> DataFlow dom cEn dEn c d-      -> DataFlow dom (aEn,cEn) (bEn,dEn) (a,c) (b,d)+parDF+  :: DataFlow dom aEn bEn a b+  -> DataFlow dom cEn dEn c d+  -> DataFlow dom (aEn, cEn) (bEn, dEn) (a, c) (b, d) f `parDF` g = firstDF f `seqDF` secondDF g  -- | Compose /n/ 'DataFlow' circuits in parallel.-parNDF :: KnownNat n-       => Vec n (DataFlow dom aEn bEn a b)-       -> DataFlow dom-                    (Vec n aEn)-                    (Vec n bEn)-                    (Vec n a)-                    (Vec n b)+parNDF+  :: KnownNat n+  => Vec n (DataFlow dom aEn bEn a b)+  -> DataFlow dom (Vec n aEn) (Vec n bEn) (Vec n a) (Vec n b) parNDF fs =   DF (\as aVs bRs ->         let as'  = unbundle as@@ -295,13 +318,13 @@ -- | Feed back the second halve of the communication channel. The feedback loop -- is buffered by a 'fifoDF' circuit. ----- So given a circuit /h/ with two synchronisation channels:+-- So given a circuit /h/ with two synchronization channels: -- -- @ -- __h__ :: 'DataFlow' (Bool,Bool) (Bool,Bool) (a,d) (b,d) -- @ ----- Feeding back the /d/ part (including its synchronisation channels) results+-- Feeding back the /d/ part (including its synchronization channels) results -- in: -- -- @@@ -310,7 +333,7 @@ -- -- <<doc/loopDF.svg>> ----- When you have a circuit @h'@, with only a single synchronisation channel:+-- When you have a circuit @h'@, with only a single synchronization channel: -- -- @ -- __h'__ :: 'DataFlow' Bool Bool (a,d) (b,d)@@ -323,7 +346,7 @@ -- @ -- -- The circuits @f@, @h@, and @g@, must operate in /lock-step/ because the /h'/--- circuit only has a single synchronisation channel. Consequently, there+-- circuit only has a single synchronization channel. Consequently, there -- should only be progress when all three circuits are producing /valid/ data -- and all three circuits are /ready/ to receive new data. We need to compose -- /h'/ with the 'lockStep' and 'stepLock' functions to achieve the /lock-step/@@ -334,21 +357,29 @@ -- @ -- -- <<doc/loopDF_sync.svg>>-loopDF :: (KnownNat m, KnownNat n, KnownNat addrSize, (m+n) ~ (2^addrSize))-       => Clock dom gated-       -> Reset dom synchronous-       -> SNat (m + n) -- ^ Depth of the FIFO buffer. Must be a power of two-       -> Vec m d -- ^ Initial content of the FIFO buffer. Can be smaller than-                  -- the size of the FIFO. Empty spaces are initialised with-                  -- 'undefined'.-       -> DataFlow dom (Bool,Bool) (Bool,Bool) (a,d) (b,d)-       -> DataFlow dom Bool Bool   a           b-loopDF clk rst sz is (DF f) =+loopDF+  :: ( KnownDomain dom+     , NFDataX d+     , KnownNat m+     , KnownNat n+     , KnownNat addrSize+     , (m+n) ~ (2^addrSize) )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> SNat (m + n)+  -- ^ Depth of the FIFO buffer. Must be a power of two+  -> Vec m d+  -- ^ Initial content of the FIFO buffer. Can be smaller than the size of the+  -- FIFO. Empty spaces are initialized with 'undefined'.+  -> DataFlow dom (Bool,Bool) (Bool,Bool) (a,d) (b,d)+  -> DataFlow dom Bool Bool   a           b+loopDF clk rst en sz is (DF f) =   DF (\a aV bR -> let (bd,bdV,adR) = f ad adV bdR                       (b,d)        = unbundle bd                       (bV,dV)      = unbundle bdV                       (aR,dR)      = unbundle adR-                      (d_buf,dV_buf,dR_buf) = df (fifoDF clk rst sz is) d dV dR+                      (d_buf,dV_buf,dR_buf) = df (fifoDF clk rst en sz is) d dV dR                        ad  = bundle (a,d_buf)                       adV = bundle (aV,dV_buf)@@ -370,9 +401,9 @@                                       in  (b,bV,aR)                          ) --- | Reduce or extend the synchronisation granularity of parallel compositions.+-- | Reduce or extend the synchronization granularity of parallel compositions. class LockStep a b where-  -- | Reduce the synchronisation granularity to a single 'Bool'ean value.+  -- | Reduce the synchronization granularity to a single 'Bool'ean value.   --   -- Given:   --@@ -389,7 +420,7 @@   -- @   --   -- because, @f \`parDF\` g@, has type, @'DataFlow' (Bool,Bool) (Bool,Bool) (a,c) (b,d)@,-  -- which does not match the expected synchronisation granularity of @h@. We+  -- which does not match the expected synchronization granularity of @h@. We   -- need a circuit in between that has the type:   --   -- @@@ -405,7 +436,7 @@   -- ready port is only asserted when @h@ is ready and @g@ is producing valid   -- data. @f@ and @g@ will hence be proceeding in /lock-step/.   ---  -- The 'lockStep' function ensures that all synchronisation signals are+  -- The 'lockStep' function ensures that all synchronization signals are   -- properly connected:   --   -- @@@ -414,7 +445,7 @@   --   -- <<doc/lockStep.svg>>   ---  -- __Note 1__: ensure that the components that you are synchronising have+  -- __Note 1__: ensure that the components that you are synchronizing have   -- buffered/delayed @ready@ and @valid@ signals, or 'lockStep' has the   -- potential to introduce combinational loops. You can do this by placing   -- 'fifoDF's on the parallel channels. Extending the above example, you would@@ -438,7 +469,7 @@   -- Does the right thing.   lockStep :: DataFlow dom a Bool b b -  -- | Extend the synchronisation granularity from a single 'Bool'ean value.+  -- | Extend the synchronization granularity from a single 'Bool'ean value.   --   -- Given:   --@@ -455,7 +486,7 @@   -- @   --   -- because, @f \`parDF\` g@, has type, @'DataFlow' (Bool,Bool) (Bool,Bool) (a,c) (b,d)@,-  -- which does not match the expected synchronisation granularity of @h@. We+  -- which does not match the expected synchronization granularity of @h@. We   -- need a circuit in between that has the type:   --   -- @@@ -471,7 +502,7 @@   -- only asserted when @h@ is valid and @f@ is ready to receive new values.   -- @f@ and @g@ will hence be proceeding in /lock-step/.   ---  -- The 'stepLock' function ensures that all synchronisation signals are+  -- The 'stepLock' function ensures that all synchronization signals are   -- properly connected:   --   -- @@@ -480,7 +511,7 @@   --   -- <<doc/stepLock.svg>>   ---  -- __Note 1__: ensure that the components that you are synchronising have+  -- __Note 1__: ensure that the components that you are synchronizing have   -- buffered/delayed @ready@ and @valid@ signals, or 'stepLock' has the   -- potential to introduce combinational loops. You can do this by placing   -- 'fifoDF's on the parallel channels. Extending the above example, you would
src/Clash/Prelude/Mealy.hs view
@@ -1,6 +1,7 @@ {-|   Copyright  :  (C) 2013-2016, University of Twente,                     2017     , Google Inc.+                    2019     , Myrtle Software Ltd   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -16,7 +17,7 @@ {-# LANGUAGE Safe #-}  module Clash.Prelude.Mealy-  ( -- * Mealy machine synchronised to the system clock+  ( -- * Mealy machine synchronized to the system clock     mealy   , mealyB   , (<^>)@@ -25,6 +26,7 @@  import qualified Clash.Explicit.Mealy as E import           Clash.Signal+import           Clash.XException           (NFDataX)  {- $setup >>> :set -XDataKinds -XTypeApplications@@ -50,12 +52,12 @@ --   where --     s' = x * y + s ----- mac :: HiddenClockReset domain gated synchronous => 'Signal' domain (Int, Int) -> 'Signal' domain Int+-- mac :: HiddenClockResetEnable dom  => 'Signal' dom (Int, Int) -> 'Signal' dom Int -- mac = 'mealy' macT 0 -- @ ----- >>> simulate mac [(1,1),(2,2),(3,3),(4,4)]--- [0,1,5,14...+-- >>> simulate @System mac [(0,0),(1,1),(2,2),(3,3),(4,4)]+-- [0,0,1,5,14... -- ... -- -- Synchronous sequential functions can be composed just like their@@ -63,23 +65,26 @@ -- -- @ -- dualMac---   :: HiddenClockReset domain gated synchronous---   => ('Signal' domain Int, 'Signal' domain Int)---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> 'Signal' domain Int+--   :: HiddenClockResetEnable dom+--   => ('Signal' dom Int, 'Signal' dom Int)+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> 'Signal' dom Int -- dualMac (a,b) (x,y) = s1 + s2 --   where --     s1 = 'mealy' mac 0 ('Clash.Signal.bundle' (a,x)) --     s2 = 'mealy' mac 0 ('Clash.Signal.bundle' (b,y)) -- @-mealy :: HiddenClockReset domain gated synchronous-      => (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:-                           -- @state -> input -> (newstate,output)@-      -> s                 -- ^ Initial state-      -> (Signal domain i -> Signal domain o)-      -- ^ Synchronous sequential function with input and output matching that-      -- of the mealy machine-mealy = hideClockReset E.mealy+mealy+  :: ( HiddenClockResetEnable dom+     , NFDataX s )+  => (s -> i -> (s,o))+  -- ^ Transfer function in mealy machine form: @state -> input -> (newstate,output)@+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealy = hideClockResetEnable E.mealy {-# INLINE mealy #-}  -- | A version of 'mealy' that does automatic 'Bundle'ing@@ -97,7 +102,7 @@ -- g a b c = (b1,b2,i2) --   where --     (i1,b1) = 'Clash.Signal.unbundle' ('mealy' f 0 ('Clash.Signal.bundle' (a,b)))---     (i2,b2) = 'Clash.Signal.unbundle' ('mealy' f 3 ('Clash.Signal.bundle' (i1,c)))+--     (i2,b2) = 'Clash.Signal.unbundle' ('mealy' f 3 ('Clash.Signal.bundle' (c,i1))) -- @ -- -- Using 'mealyB' however we can write:@@ -106,25 +111,35 @@ -- g a b c = (b1,b2,i2) --   where --     (i1,b1) = 'mealyB' f 0 (a,b)---     (i2,b2) = 'mealyB' f 3 (i1,c)+--     (i2,b2) = 'mealyB' f 3 (c,i1) -- @-mealyB :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous)-       => (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:-                            -- @state -> input -> (newstate,output)@-       -> s                 -- ^ Initial state-       -> (Unbundled domain i -> Unbundled domain o)-       -- ^ Synchronous sequential function with input and output matching that-       -- of the mealy machine-mealyB = hideClockReset E.mealyB+mealyB+  :: ( HiddenClockResetEnable dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => (s -> i -> (s,o))+  -- ^ Transfer function in mealy machine form: @state -> input -> (newstate,output)@+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealyB = hideClockResetEnable E.mealyB {-# INLINE mealyB #-}  -- | Infix version of 'mealyB'-(<^>) :: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous)-      => (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:-                           -- @state -> input -> (newstate,output)@-      -> s                 -- ^ Initial state-      -> (Unbundled domain i -> Unbundled domain o)-      -- ^ Synchronous sequential function with input and output matching that-      -- of the mealy machine+(<^>)+  :: ( HiddenClockResetEnable dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => (s -> i -> (s,o))+  -- ^ Transfer function in mealy machine form: @state -> input -> (newstate,output)@+  -> s+  -- ^ Initial state+ -> (Unbundled dom i -> Unbundled dom o)+ -- ^ Synchronous sequential function with input and output matching that+ -- of the mealy machine (<^>) = mealyB {-# INLINE (<^>) #-}
src/Clash/Prelude/Moore.hs view
@@ -1,6 +1,7 @@ {-|   Copyright  :  (C) 2013-2016, University of Twente                     2017     , Google Inc.+                    2019     , Myrtle Software Ltd   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -26,6 +27,7 @@  import qualified Clash.Explicit.Moore as E import           Clash.Signal+import           Clash.XException                     (NFDataX)  {- $setup >>> :set -XDataKinds -XTypeApplications@@ -42,17 +44,21 @@ -- a moore machine -- -- @--- macT :: Int        -- Current state---      -> (Int,Int)  -- Input---      -> Int        -- Updated state+-- macT+--   :: Int        -- Current state+--   -> (Int,Int)  -- Input+--   -> Int        -- Updated state -- macT s (x,y) = x * y + s ----- mac :: HiddenClockReset domain gated synchronous => 'Signal' domain (Int, Int) -> 'Signal' domain Int+-- mac+--   :: HiddenClockResetEnable dom+--   => 'Signal' dom (Int, Int)+--   -> 'Signal' dom Int -- mac = 'moore' mac id 0 -- @ ----- >>> simulate mac [(1,1),(2,2),(3,3),(4,4)]--- [0,1,5,14...+-- >>> simulate @System mac [(0,0),(1,1),(2,2),(3,3),(4,4)]+-- [0,0,1,5,14,30,... -- ... -- -- Synchronous sequential functions can be composed just like their@@ -60,36 +66,39 @@ -- -- @ -- dualMac---   :: HiddenClockReset domain gated synchronous---   => ('Signal' domain Int, 'Signal' domain Int)---   -> ('Signal' domain Int, 'Signal' domain Int)---   -> 'Signal' domain Int+--   :: HiddenClockResetEnable dom+--   => ('Signal' dom Int, 'Signal' dom Int)+--   -> ('Signal' dom Int, 'Signal' dom Int)+--   -> 'Signal' dom Int -- dualMac (a,b) (x,y) = s1 + s2 --   where --     s1 = 'moore' mac id 0 ('Clash.Signal.bundle' (a,x)) --     s2 = 'moore' mac id 0 ('Clash.Signal.bundle' (b,y)) -- @ moore-  :: HiddenClockReset domain gated synchronous-  => (s -> i -> s) -- ^ Transfer function in moore machine form:-                   -- @state -> input -> newstate@-  -> (s -> o)      -- ^ Output function in moore machine form:-                   -- @state -> output@-  -> s             -- ^ Initial state-  -> (Signal domain i -> Signal domain o)+  :: ( HiddenClockResetEnable dom+     , NFDataX s )+  => (s -> i -> s)+  -- ^ Transfer function in moore machine form: @state -> input -> newstate@+  -> (s -> o)+  -- ^ Output function in moore machine form: @state -> output@+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)   -- ^ Synchronous sequential function with input and output matching that   -- of the moore machine-moore = hideClockReset E.moore+moore = hideClockResetEnable E.moore {-# INLINE moore #-}   -- | Create a synchronous function from a combinational function describing -- a moore machine without any output logic medvedev-  :: HiddenClockReset domain gated synchronous+  :: ( HiddenClockResetEnable dom+     , NFDataX s )   => (s -> i -> s)   -> s-  -> (Signal domain i -> Signal domain s)+  -> (Signal dom i -> Signal dom s) medvedev tr st = moore tr id st {-# INLINE medvedev #-} @@ -109,7 +118,7 @@ -- g a b c = (b1,b2,i2) --   where --     (i1,b1) = 'Clash.Signal.unbundle' ('moore' t o 0 ('Clash.Signal.bundle' (a,b)))---     (i2,b2) = 'Clash.Signal.unbundle' ('moore' t o 3 ('Clash.Signal.bundle' (i1,c)))+--     (i2,b2) = 'Clash.Signal.unbundle' ('moore' t o 3 ('Clash.Signal.bundle' (c,i1))) -- @ -- -- Using 'mooreB' however we can write:@@ -118,26 +127,33 @@ -- g a b c = (b1,b2,i2) --   where --     (i1,b1) = 'mooreB' t o 0 (a,b)---     (i2,b2) = 'mooreB' t o 3 (i1,c)+--     (i2,b2) = 'mooreB' t o 3 (c,i1) -- @ mooreB-  :: (Bundle i, Bundle o,HiddenClockReset domain gated synchronous)-  => (s -> i -> s) -- ^ Transfer function in moore machine form:-                   -- @state -> input -> newstate@-  -> (s -> o)      -- ^ Output function in moore machine form:-                   -- @state -> output@-  -> s             -- ^ Initial state-  -> (Unbundled domain i -> Unbundled domain o)+  :: ( HiddenClockResetEnable dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => (s -> i -> s)+  -- ^ Transfer function in moore machine form: @state -> input -> newstate@+  -> (s -> o)+  -- ^ Output function in moore machine form: @state -> output@+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)    -- ^ Synchronous sequential function with input and output matching that    -- of the moore machine-mooreB = hideClockReset E.mooreB+mooreB = hideClockResetEnable E.mooreB {-# INLINE mooreB #-}  -- | A version of 'medvedev' that does automatic 'Bundle'ing medvedevB-  :: (Bundle i, Bundle s, HiddenClockReset domain gated synchronous)+  :: ( HiddenClockResetEnable dom+     , NFDataX s+     , Bundle i+     , Bundle s )   => (s -> i -> s)   -> s-  -> (Unbundled domain i -> Unbundled domain s)+  -> (Unbundled dom i -> Unbundled dom s) medvedevB tr st = mooreB tr id st {-# INLINE medvedevB #-}
src/Clash/Prelude/RAM.hs view
@@ -1,6 +1,7 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2017-2019, Myrtle Software Ltd+                  2017     , Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -22,7 +23,7 @@ {-# OPTIONS_HADDOCK show-extensions #-}  module Clash.Prelude.RAM-  ( -- * RAM synchronised to an arbitrary clock+  ( -- * RAM synchronized to an arbitrary clock     asyncRam   , asyncRamPow2   )@@ -46,17 +47,21 @@ -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- RAM. asyncRam-  :: (Enum addr, HiddenClock domain gated, HasCallStack)+  :: ( Enum addr+     , HiddenClock dom+     , HiddenEnable dom+     , HasCallStack+     )   => SNat n   -- ^ Size @n@ of the RAM-  -> Signal domain addr+  -> Signal dom addr   -- ^ Read address @r@-  -> Signal domain (Maybe (addr, a))+  -> Signal dom (Maybe (addr, a))    -- ^ (write address @w@, value to write)-  -> Signal domain a+  -> Signal dom a    -- ^ Value of the @RAM@ at address @r@ asyncRam = \sz rd wrM -> withFrozenCallStack-  (hideClock (\clk -> E.asyncRam clk clk sz rd wrM))+  (hideEnable (\en -> hideClock (\clk -> E.asyncRam clk clk en sz rd wrM))) {-# INLINE asyncRam #-}  -- | Create a RAM with space for 2^@n@ elements@@ -68,13 +73,16 @@ -- * See "Clash.Prelude.BlockRam#usingrams" for more information on how to use a -- RAM. asyncRamPow2-  :: (KnownNat n, HiddenClock domain gated, HasCallStack)-  => Signal domain (Unsigned n)+  :: ( KnownNat n+     , HiddenClock dom+     , HiddenEnable dom+     , HasCallStack )+  => Signal dom (Unsigned n)   -- ^ Read address @r@-  -> Signal domain (Maybe (Unsigned n, a))+  -> Signal dom (Maybe (Unsigned n, a))   -- ^ (write address @w@, value to write)-  -> Signal domain a+  -> Signal dom a   -- ^ Value of the @RAM@ at address @r@ asyncRamPow2 = \rd wrM -> withFrozenCallStack-  (hideClock (\clk -> E.asyncRamPow2 clk clk rd wrM))+  (hideEnable (\en -> (hideClock (\clk -> E.asyncRamPow2 clk clk en rd wrM)))) {-# INLINE asyncRamPow2 #-}
src/Clash/Prelude/ROM.hs view
@@ -1,6 +1,7 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -10,6 +11,7 @@ {-# LANGUAGE DataKinds        #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MagicHash        #-}+{-# LANGUAGE RankNTypes       #-} {-# LANGUAGE TypeOperators    #-}  {-# LANGUAGE Safe #-}@@ -21,7 +23,7 @@   ( -- * Asynchronous ROM     asyncRom   , asyncRomPow2-    -- * Synchronous ROM synchronised to an arbitrary clock+    -- * Synchronous ROM synchronized to an arbitrary clock   , rom   , romPow2     -- * Internal@@ -38,18 +40,24 @@ import           Clash.Sized.Unsigned (Unsigned) import           Clash.Sized.Vector   (Vec, length, toList) +import           Clash.XException     (NFDataX)+ -- | An asynchronous/combinational ROM with space for @n@ elements -- -- Additional helpful information: -- -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Prelude.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs-asyncRom :: (KnownNat n, Enum addr)-         => Vec n a -- ^ ROM content-                    ---                    -- __NB:__ must be a constant-         -> addr    -- ^ Read address @rd@-         -> a       -- ^ The value of the ROM at address @rd@+asyncRom+  :: (KnownNat n, Enum addr)+  => Vec n a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> addr+  -- ^ Read address @rd@+  -> a+  -- ^ The value of the ROM at address @rd@ asyncRom = \content rd -> asyncRom# content (fromEnum rd) {-# INLINE asyncRom #-} @@ -59,22 +67,30 @@ -- -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Prelude.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs-asyncRomPow2 :: KnownNat n-             => Vec (2^n) a -- ^ ROM content-                            ---                            -- __NB:__ must be a constant-             -> Unsigned n  -- ^ Read address @rd@-             -> a           -- ^ The value of the ROM at address @rd@+asyncRomPow2+  :: KnownNat n+  => Vec (2^n) a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Unsigned n+  -- ^ Read address @rd@+  -> a+  -- ^ The value of the ROM at address @rd@ asyncRomPow2 = asyncRom {-# INLINE asyncRomPow2 #-}  -- | asyncROM primitive-asyncRom# :: KnownNat n-          => Vec n a  -- ^ ROM content-                      ---                      -- __NB:__ must be a constant-          -> Int      -- ^ Read address @rd@-          -> a        -- ^ The value of the ROM at address @rd@+asyncRom#+  :: KnownNat n+  => Vec n a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Int+  -- ^ Read address @rd@+  -> a+  -- ^ The value of the ROM at address @rd@ asyncRom# content rd = arr ! rd   where     szI = length content@@ -91,13 +107,21 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Prelude.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs rom-  :: (KnownNat n, KnownNat m, HiddenClock domain gated)-  => Vec n a               -- ^ ROM content-                           ---                           -- __NB:__ must be a constant-  -> Signal domain (Unsigned m)   -- ^ Read address @rd@-  -> Signal domain a              -- ^ The value of the ROM at address @rd@-rom = hideClock E.rom+  :: forall dom n m a+   . ( NFDataX a+     , KnownNat n+     , KnownNat m+     , HiddenClock dom+     , HiddenEnable dom  )+  => Vec n a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Signal dom (Unsigned m)+  -- ^ Read address @rd@+  -> Signal dom a+  -- ^ The value of the ROM at address @rd@+rom = hideEnable (hideClock E.rom) {-# INLINE rom #-}  -- | A ROM with a synchronous read port, with space for 2^@n@ elements@@ -110,11 +134,18 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" and "Clash.Prelude.BlockRam#usingrams" -- for ideas on how to use ROMs and RAMs romPow2-  :: (KnownNat n, HiddenClock domain gated)-  => Vec (2^n) a         -- ^ ROM content-                         ---                         -- __NB:__ must be a constant-  -> Signal domain (Unsigned n) -- ^ Read address @rd@-  -> Signal domain a            -- ^ The value of the ROM at address @rd@-romPow2 = hideClock E.romPow2+  :: forall dom n a+   . ( KnownNat n+     , NFDataX a+     , HiddenClock dom+     , HiddenEnable dom  )+  => Vec (2^n) a+  -- ^ ROM content+  --+  -- __NB:__ must be a constant+  -> Signal dom (Unsigned n)+  -- ^ Read address @rd@+  -> Signal dom a+  -- ^ The value of the ROM at address @rd@+romPow2 = hideEnable (hideClock E.romPow2) {-# INLINE romPow2 #-}
src/Clash/Prelude/ROM/File.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -= Initialising a ROM with a data file #usingromfiles#+= Initializing a ROM with a data file #usingromfiles# -ROMs initialised with a data file. The BNF grammar for this data file is simple:+ROMs initialized with a data file. The BNF grammar for this data file is simple:  @ FILE = LINE+@@ -33,7 +34,7 @@ so:  @-f :: HiddenClock domain => Signal domain (Unsigned 3) -> Signal domain (Unsigned 9)+f :: HiddenClock dom  => Signal dom (Unsigned 3) -> Signal dom (Unsigned 9) f rd = 'Clash.Class.BitPack.unpack' '<$>' 'romFile' d7 \"memory.bin\" rd @ @@ -49,7 +50,7 @@ number, and a 3-bit signed number:  @-g :: HiddenClock domain => Signal domain (Unsigned 3) -> Signal domain (Unsigned 6,Signed 3)+g :: HiddenClock dom  => Signal dom (Unsigned 3) -> Signal dom (Unsigned 6,Signed 3) g rd = 'Clash.Class.BitPack.unpack' '<$>' 'romFile' d7 \"memory.bin\" rd @ @@ -77,7 +78,7 @@   ( -- * Asynchronous ROM     asyncRomFile   , asyncRomFilePow2-    -- * Synchronous ROM synchronised to an arbitrary clock+    -- * Synchronous ROM synchronized to an arbitrary clock   , romFile   , romFilePow2     -- * Internal@@ -140,10 +141,14 @@ --     @ asyncRomFile   :: (KnownNat m, Enum addr)-  => SNat n      -- ^ Size of the ROM-  -> FilePath    -- ^ File describing the content of the ROM-  -> addr        -- ^ Read address @rd@-  -> BitVector m -- ^ The value of the ROM at address @rd@+  => SNat n+  -- ^ Size of the ROM+  -> FilePath+  -- ^ File describing the content of the ROM+  -> addr+  -- ^ Read address @rd@+  -> BitVector m+  -- ^ The value of the ROM at address @rd@ asyncRomFile sz file = asyncRomFile# sz file . fromEnum -- Leave 'asyncRom' eta-reduced, see Note [Eta-reduction and unsafePerformIO initMem] {-# INLINE asyncRomFile #-}@@ -214,19 +219,26 @@ asyncRomFilePow2   :: forall n m    . (KnownNat m, KnownNat n)-  => FilePath    -- ^ File describing the content of the ROM-  -> Unsigned n  -- ^ Read address @rd@-  -> BitVector m -- ^ The value of the ROM at address @rd@+  => FilePath+  -- ^ File describing the content of the ROM+  -> Unsigned n+  -- ^ Read address @rd@+  -> BitVector m+  -- ^ The value of the ROM at address @rd@ asyncRomFilePow2 = asyncRomFile (pow2SNat (SNat @ n)) {-# INLINE asyncRomFilePow2 #-}  -- | asyncROMFile primitive asyncRomFile#   :: KnownNat m-  => SNat n       -- ^ Size of the ROM-  -> FilePath     -- ^ File describing the content of the ROM-  -> Int          -- ^ Read address @rd@-  -> BitVector m  -- ^ The value of the ROM at address @rd@+  => SNat n+  -- ^ Size of the ROM+  -> FilePath+  -- ^ File describing the content of the ROM+  -> Int+  -- ^ Read address @rd@+  -> BitVector m+  -- ^ The value of the ROM at address @rd@ asyncRomFile# sz file = (content !) -- Leave "(content !)" eta-reduced, see   where                             -- Note [Eta-reduction and unsafePerformIO initMem]     mem     = unsafePerformIO (initMem file)@@ -258,13 +270,20 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. romFile-  :: (KnownNat m, KnownNat n, HiddenClock domain gated)-  => SNat n               -- ^ Size of the ROM-  -> FilePath             -- ^ File describing the content of the ROM-  -> Signal domain (Unsigned n)  -- ^ Read address @rd@-  -> Signal domain (BitVector m)+  :: ( KnownNat m+     , KnownNat n+     , HiddenClock dom+     , HiddenEnable dom+     )+  => SNat n+  -- ^ Size of the ROM+  -> FilePath+  -- ^ File describing the content of the ROM+  -> Signal dom (Unsigned n)+  -- ^ Read address @rd@+  -> Signal dom (BitVector m)   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-romFile = hideClock E.romFile+romFile = hideEnable (hideClock E.romFile) {-# INLINE romFile #-}  -- | A ROM with a synchronous read port, with space for 2^@n@ elements@@ -291,11 +310,17 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" for ideas on how to create your -- own data files. romFilePow2-  :: forall n m domain gated-   . (KnownNat m, KnownNat n, HiddenClock domain gated)-  => FilePath                    -- ^ File describing the content of the ROM-  -> Signal domain (Unsigned n)  -- ^ Read address @rd@-  -> Signal domain (BitVector m)+  :: forall n m dom+   . ( KnownNat m+     , KnownNat n+     , HiddenClock dom+     , HiddenEnable dom+     )+  => FilePath+  -- ^ File describing the content of the ROM+  -> Signal dom (Unsigned n)+  -- ^ Read address @rd@+  -> Signal dom (BitVector m)   -- ^ The value of the ROM at address @rd@ from the previous clock cycle-romFilePow2 = hideClock E.romFilePow2+romFilePow2 = hideEnable (hideClock E.romFilePow2) {-# INLINE romFilePow2 #-}
src/Clash/Prelude/Safe.hs view
@@ -1,17 +1,18 @@ {-|   Copyright   :  (C) 2013-2016, University of Twente,-                     2017     , Myrtle Software Ltd, Google Inc.+                     2017-2019, Myrtle Software Ltd+                     2017     , Google Inc.   License     :  BSD2 (see the file LICENSE)   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>    __This is the <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe_haskell.html Safe> API only of "Clash.Prelude"__ -  CλaSH (pronounced ‘clash’) is a functional hardware description language that-  borrows both its syntax and semantics from the functional programming language-  Haskell. The merits of using a functional language to describe hardware comes-  from the fact that combinational circuits can be directly modeled as-  mathematical functions and that functional languages lend themselves very well-  at describing and (de-)composing mathematical functions.+  Clash is a functional hardware description language that borrows both its+  syntax and semantics from the functional programming language Haskell. The+  merits of using a functional language to describe hardware comes from the fact+  that combinational circuits can be directly modeled as mathematical functions+  and that functional languages lend themselves very well at describing and+  (de-)composing mathematical functions.    This package provides: @@ -30,11 +31,12 @@  {-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE NoImplicitPrelude   #-} {-# LANGUAGE TypeOperators       #-}  {-# LANGUAGE Safe #-} -{-# OPTIONS_HADDOCK show-extensions #-}+{-# OPTIONS_HADDOCK show-extensions, not-home #-}  module Clash.Prelude.Safe   ( -- * Creating synchronous sequential circuits@@ -85,6 +87,9 @@   , module Clash.Sized.RTree     -- ** Annotations   , module Clash.Annotations.TopEntity+    -- ** Generics type-classes+  , Generic+  , Generic1     -- ** Type-level natural numbers   , module GHC.TypeLits   , module GHC.TypeLits.Extra@@ -110,18 +115,17 @@   , module Clash.Hidden     -- ** Haskell Prelude     -- $hiding-  , module Prelude+  , module Clash.HaskellPrelude   ) where  import           Control.Applicative import           Data.Bits+import           GHC.Generics (Generic, Generic1)+ import           GHC.TypeLits import           GHC.TypeLits.Extra-import           Prelude hiding-  ((++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate,-   last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt, tail,-   take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined)+import           Clash.HaskellPrelude  import           Clash.Annotations.TopEntity import           Clash.Class.BitPack@@ -170,39 +174,49 @@  -- | Create a 'register' function for product-type like signals (e.g. '(Signal a, Signal b)') ----- > rP :: HiddenClockReset domain gated synchronous--- >    => (Signal domain Int, Signal domain Int)--- >    -> (Signal domain Int, Signal domain Int)+-- > rP :: HiddenClockResetEnable dom+-- >    => (Signal dom Int, Signal dom Int)+-- >    -> (Signal dom Int, Signal dom Int) -- > rP = registerB (8,8) ----- >>> simulateB rP [(1,1),(2,2),(3,3)] :: [(Int,Int)]+-- >>> simulateB @System rP [(1,1),(2,2),(3,3)] :: [(Int,Int)] -- [(8,8),(1,1),(2,2),(3,3)... -- ... registerB-  :: (HiddenClockReset domain gated synchronous, Bundle a)+  :: ( HiddenClockResetEnable dom+     , NFDataX a+     , Bundle a )   => a-  -> Unbundled domain a-  -> Unbundled domain a-registerB = hideClockReset E.registerB+  -> Unbundled dom a+  -> Unbundled dom a+registerB = hideClockResetEnable E.registerB infixr 3 `registerB` {-# INLINE registerB #-}  -- | Give a pulse when the 'Signal' goes from 'minBound' to 'maxBound' isRising-  :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a)-  => a -- ^ Starting value-  -> Signal domain a-  -> Signal domain Bool-isRising = hideClockReset E.isRising+  :: ( HiddenClockResetEnable dom+     , NFDataX a+     , Bounded a+     , Eq a )+  => a+  -- ^ Starting value+  -> Signal dom a+  -> Signal dom Bool+isRising = hideClockResetEnable E.isRising {-# INLINE isRising #-}  -- | Give a pulse when the 'Signal' goes from 'maxBound' to 'minBound' isFalling-  :: (HiddenClockReset domain gated synchronous, Bounded a, Eq a)-  => a -- ^ Starting value-  -> Signal domain a-  -> Signal domain Bool-isFalling = hideClockReset E.isFalling+  :: ( HiddenClockResetEnable dom+     , NFDataX a+     , Bounded a+     , Eq a )+  => a+  -- ^ Starting value+  -> Signal dom a+  -> Signal dom Bool+isFalling = hideClockResetEnable E.isFalling {-# INLINE isFalling #-}  -- | Give a pulse every @n@ clock cycles. This is a useful helper function when@@ -212,9 +226,9 @@ -- To be precise: the given signal will be @'False'@ for the next @n-1@ cycles, -- followed by a single @'True'@ value: ----- >>> Prelude.last (sampleN 1024 (riseEvery d1024)) == True+-- >>> Prelude.last (sampleN @System 1025 (riseEvery d1024)) == True -- True--- >>> Prelude.or (sampleN 1023 (riseEvery d1024)) == False+-- >>> Prelude.or (sampleN @System 1024 (riseEvery d1024)) == False -- True -- -- For example, to update a counter once every 10 million cycles:@@ -223,10 +237,10 @@ -- counter = 'Clash.Signal.regEn' 0 ('riseEvery' ('SNat' :: 'SNat' 10000000)) (counter + 1) -- @ riseEvery-  :: HiddenClockReset domain gated synchronous+  :: HiddenClockResetEnable dom   => SNat n-  -> Signal domain Bool-riseEvery = hideClockReset E.riseEvery+  -> Signal dom Bool+riseEvery = hideClockResetEnable E.riseEvery {-# INLINE riseEvery #-}  -- | Oscillate a @'Bool'@ for a given number of cycles. This is a convenient@@ -236,24 +250,23 @@ -- -- To oscillate on an interval of 5 cycles: ----- >>> sampleN 10 (oscillate False d5)--- [False,False,False,False,False,True,True,True,True,True]+-- >>> sampleN @System 11 (oscillate False d5)+-- [False,False,False,False,False,False,True,True,True,True,True] -- -- To oscillate between @'True'@ and @'False'@: ----- >>> sampleN 10 (oscillate False d1)--- [False,True,False,True,False,True,False,True,False,True]+-- >>> sampleN @System 11 (oscillate False d1)+-- [False,False,True,False,True,False,True,False,True,False,True] -- -- An alternative definition for the above could be: -- -- >>> let osc' = register False (not <$> osc')--- >>> let sample' = sampleN 200--- >>> sample' (oscillate False d1) == sample' osc'+-- >>> sampleN @System 200 (oscillate False d1) == sampleN @System 200 osc' -- True oscillate-  :: HiddenClockReset domain gated synchronous+  :: HiddenClockResetEnable dom   => Bool   -> SNat n-  -> Signal domain Bool-oscillate = hideClockReset E.oscillate+  -> Signal dom Bool+oscillate = hideClockResetEnable E.oscillate {-# INLINE oscillate #-}
+ src/Clash/Prelude/Synchronizer.hs view
@@ -0,0 +1,89 @@+{-|+Copyright   :  (C) 2019, Myrtle Software Ltd,+License     :  BSD2 (see the file LICENSE)+Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>++Synchronizer circuits for safe clock domain crossings+-}++{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE TypeFamilies          #-}++module Clash.Prelude.Synchronizer+  ( -- * Bit-synchronizers+    dualFlipFlopSynchronizer+    -- * Word-synchronizers+  , asyncFIFOSynchronizer+  ) where++import qualified Clash.Explicit.Synchronizer as E+import           Clash.Promoted.Nat          (SNat)+import           Clash.Signal+  (HiddenClockResetEnable, HiddenClock, Signal, hasClock, hasReset, hasEnable)+import           Clash.XException            (NFDataX)+import           GHC.TypeLits                (type (<=))++-- | Synchronizer based on two sequentially connected flip-flops.+--+--  * __NB__: This synchronizer can be used for __bit__-synchronization.+--+--  * __NB__: Although this synchronizer does reduce metastability, it does+--  not guarantee the proper synchronization of a whole __word__. For+--  example, given that the output is sampled twice as fast as the input is+--  running, and we have two samples in the input stream that look like:+--+--      @[0111,1000]@+--+--      But the circuit driving the input stream has a longer propagation delay+--      on __msb__ compared to the __lsb__s. What can happen is an output stream+--      that looks like this:+--+--      @[0111,0111,0000,1000]@+--+--      Where the level-change of the __msb__ was not captured, but the level+--      change of the __lsb__s were.+--+--      If you want to have /safe/ __word__-synchronization use+--      'asyncFIFOSynchronizer'.+dualFlipFlopSynchronizer+  :: ( NFDataX a+     , HiddenClock dom1+     , HiddenClockResetEnable dom2+     )+  => a+  -- ^ Initial value of the two synchronization registers+  -> Signal dom1 a+  -- ^ Incoming data+  -> Signal dom2 a+  -- ^ Outgoing, synchronized, data+dualFlipFlopSynchronizer =+  E.dualFlipFlopSynchronizer hasClock hasClock hasReset hasEnable++-- | Synchronizer implemented as a FIFO around an asynchronous RAM. Based on the+-- design described in "Clash.Tutorial#multiclock", which is itself based on the+-- design described in <http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf>.+--+-- __NB__: This synchronizer can be used for __word__-synchronization.+asyncFIFOSynchronizer+  :: ( HiddenClockResetEnable rdom+     , HiddenClockResetEnable wdom+     , 2 <= addrSize )+  => SNat addrSize+  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@+  -- elements.+  -> Signal rdom Bool+  -- ^ Read request+  -> Signal wdom (Maybe a)+  -- ^ Element to insert+  -> (Signal rdom a, Signal rdom Bool, Signal wdom Bool)+  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)+asyncFIFOSynchronizer addrSize =+  E.asyncFIFOSynchronizer+    addrSize+    hasClock  -- wdom+    hasClock  -- rdom+    hasReset  -- wdom+    hasReset  -- rdom+    hasEnable  -- wdom+    hasEnable  -- rdom
src/Clash/Prelude/Testbench.hs view
@@ -1,11 +1,14 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} +{-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE TypeFamilies        #-} {-# LANGUAGE ScopedTypeVariables #-}  {-# LANGUAGE Unsafe #-}@@ -15,8 +18,14 @@ module Clash.Prelude.Testbench   ( -- * Testbench functions for circuits     assert+  , ignoreFor+  , outputVerifier'+  , outputVerifierBitVector'   , stimuliGenerator-  , outputVerifier++  , E.tbClockGen+  , E.tbEnableGen+  , E.tbSystemClockGen   ) where @@ -24,7 +33,10 @@  import qualified Clash.Explicit.Testbench as E import           Clash.Signal-  (HiddenClockReset, Signal, hideClockReset)+  (HiddenClock, HiddenReset, HiddenClockResetEnable, Signal,+  DomainResetKind, ResetKind(Asynchronous), hideClock, hideReset, hideClockResetEnable)+import Clash.Promoted.Nat                 (SNat)+import Clash.Sized.BitVector              (BitVector) import Clash.Sized.Vector                 (Vec) import Clash.XException                   (ShowX) @@ -32,86 +44,134 @@ >>> :set -XTemplateHaskell -XDataKinds -XTypeApplications >>> import Clash.Prelude >>> let testInput = stimuliGenerator $(listToVecTH [(1::Int),3..21])->>> let expectedOutput = outputVerifier $(listToVecTH ([70,99,2,3,4,5,7,8,9,10]::[Int]))+>>> let expectedOutput = outputVerifier' $(listToVecTH ([70,99,2,3,4,5,7,8,9,10]::[Int])) -}  -- | Compares the first two 'Signal's for equality and logs a warning when they -- are not equal. The second 'Signal' is considered the expected value. This -- function simply returns the third 'Signal' unaltered as its result. This--- function is used by 'outputVerifier'.+-- function is used by 'outputVerifier''. -- -- -- __NB__: This function /can/ be used in synthesizable designs. assert-  :: (Eq a,ShowX a,HiddenClockReset domain gated synchronous)-  => String   -- ^ Additional message-  -> Signal domain a -- ^ Checked value-  -> Signal domain a -- ^ Expected value-  -> Signal domain b -- ^ Return value-  -> Signal domain b-assert = hideClockReset E.assert+  :: (Eq a, ShowX a, HiddenClock dom , HiddenReset dom )+  => String+  -- ^ Additional message+  -> Signal dom a+  -- ^ Checked value+  -> Signal dom a+  -- ^ Expected value+  -> Signal dom b+  -- ^ Return value+  -> Signal dom b+assert msg actual expected ret =+  hideReset (hideClock E.assert) msg actual expected ret {-# INLINE assert #-} --- | To be used as one of the functions to create the \"magical\" 'testInput'--- value, which the CλaSH compiler looks for to create the stimulus generator--- for the generated VHDL testbench.+-- | -- -- Example: -- -- @ -- testInput---   :: HiddenClockReset domain gated synchronous---   => 'Signal' domain Int+--   :: HiddenClockResetEnable dom+--   => 'Signal' dom Int -- testInput = 'stimuliGenerator' $('Clash.Sized.Vector.listToVecTH' [(1::Int),3..21]) -- @ -- -- >>> sampleN 13 testInput -- [1,3,5,7,9,11,13,15,17,19,21,21,21] stimuliGenerator-  :: (KnownNat l, HiddenClockReset domain gated synchronous)-  => Vec l a  -- ^ Samples to generate-  -> Signal domain a -- ^ Signal of given samples-stimuliGenerator = hideClockReset E.stimuliGenerator+  :: ( KnownNat l+     , HiddenClock dom+     , HiddenReset dom  )+  => Vec l a+  -- ^ Samples to generate+  -> Signal dom a+  -- ^ Signal of given samples+stimuliGenerator = hideReset (hideClock E.stimuliGenerator) {-# INLINE stimuliGenerator #-} --- | To be used as one of the functions to generate the \"magical\" 'expectedOutput'--- function, which the CλaSH compiler looks for to create the signal verifier--- for the generated VHDL testbench.+-- | -- -- Example: -- -- @ -- expectedOutput---   :: HiddenClockReset domain gated synchronous---   -> 'Signal' domain Int -> 'Signal' domain Bool--- expectedOutput = 'outputVerifier' $('Clash.Sized.Vector.listToVecTH' ([70,99,2,3,4,5,7,8,9,10]::[Int]))+--   :: HiddenClockResetEnable dom+--   -> 'Signal' dom Int -> 'Signal' dom Bool+-- expectedOutput = 'outputVerifier'' $('Clash.Sized.Vector.listToVecTH' ([70,99,2,3,4,5,7,8,9,10]::[Int])) -- @ -- -- >>> import qualified Data.List as List -- >>> sampleN 12 (expectedOutput (fromList ([0..10] List.++ [10,10,10]))) -- <BLANKLINE>--- cycle(system10000): 0, outputVerifier+-- cycle(system10000): 0, outputVerifier' -- expected value: 70, not equal to actual value: 0 -- [False--- cycle(system10000): 1, outputVerifier+-- cycle(system10000): 1, outputVerifier' -- expected value: 99, not equal to actual value: 1 -- ,False,False,False,False,False--- cycle(system10000): 6, outputVerifier+-- cycle(system10000): 6, outputVerifier' -- expected value: 7, not equal to actual value: 6 -- ,False--- cycle(system10000): 7, outputVerifier+-- cycle(system10000): 7, outputVerifier' -- expected value: 8, not equal to actual value: 7 -- ,False--- cycle(system10000): 8, outputVerifier+-- cycle(system10000): 8, outputVerifier' -- expected value: 9, not equal to actual value: 8 -- ,False--- cycle(system10000): 9, outputVerifier+-- cycle(system10000): 9, outputVerifier' -- expected value: 10, not equal to actual value: 9 -- ,False,True,True]-outputVerifier-  :: (KnownNat l, Eq a, ShowX a, HiddenClockReset domain gated synchronous)-  => Vec l a     -- ^ Samples to compare with-  -> Signal domain a    -- ^ Signal to verify-  -> Signal domain Bool -- ^ Indicator that all samples are verified-outputVerifier = hideClockReset E.outputVerifier-{-# INLINE outputVerifier #-}+--+-- If your working with 'BitVector's containing don't care bits you should use 'outputVerifierBitVector''.+outputVerifier'+  :: ( KnownNat l+     , Eq a+     , ShowX a+     , DomainResetKind dom ~ 'Asynchronous+     , HiddenClock dom+     , HiddenReset dom  )+  => Vec l a+  -- ^ Samples to compare with+  -> Signal dom a+  -- ^ Signal to verify+  -> Signal dom Bool+  -- ^ Indicator that all samples are verified+outputVerifier' = hideReset (hideClock E.outputVerifier')+{-# INLINE outputVerifier' #-}+++-- | Same as 'outputVerifier'',+-- but can handle don't care bits in it's expected values.+outputVerifierBitVector'+  :: ( KnownNat l+     , KnownNat n+     , DomainResetKind dom ~ 'Asynchronous+     , HiddenClock dom+     , HiddenReset dom  )+  => Vec l (BitVector n)+  -- ^ Samples to compare with+  -> Signal dom (BitVector n)+  -- ^ Signal to verify+  -> Signal dom Bool+  -- ^ Indicator that all samples are verified+outputVerifierBitVector' = hideReset (hideClock E.outputVerifierBitVector')+{-# INLINE outputVerifierBitVector' #-}++-- | Ignore signal for a number of cycles, while outputting a static value.+ignoreFor+  :: HiddenClockResetEnable dom+  => SNat n+  -- ^ Number of cycles to ignore incoming signal+  -> a+  -- ^ Value function produces when ignoring signal+  -> Signal dom a+  -- ^ Incoming signal+  -> Signal dom a+  -- ^ Either a passthrough of the incoming signal, or the static value+  -- provided as the second argument.+ignoreFor = hideClockResetEnable E.ignoreFor+{-# INLINE ignoreFor #-}
src/Clash/Promoted/Nat.hs view
@@ -6,6 +6,7 @@ -}  {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP                 #-} {-# LANGUAGE DataKinds           #-} {-# LANGUAGE GADTs               #-} {-# LANGUAGE KindSignatures      #-}@@ -15,6 +16,9 @@ {-# LANGUAGE TypeApplications    #-} {-# LANGUAGE TypeOperators       #-} {-# LANGUAGE RankNTypes          #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  {-# LANGUAGE Trustworthy #-} @@ -31,13 +35,15 @@   , snatProxy   , withSNat     -- ** Conversion-  , snatToInteger, snatToNum+  , snatToInteger, snatToNatural, snatToNum     -- ** Arithmetic-  , addSNat, mulSNat, powSNat+  , addSNat, mulSNat, powSNat, minSNat, maxSNat, succSNat     -- *** Partial-  , subSNat, divSNat, modSNat, flogBaseSNat, clogBaseSNat, logBaseSNat+  , subSNat, divSNat, modSNat, flogBaseSNat, clogBaseSNat, logBaseSNat, predSNat     -- *** Specialised   , pow2SNat+    -- *** Comparison+  , SNatLE (..), compareSNat     -- * Unary/Peano-encoded natural numbers     -- ** Data type   , UNat (..)@@ -67,16 +73,17 @@     -- * Constraints on natural numbers   , leToPlus   , leToPlusKN-  , plusToLe-  , plusToLeKN   ) where +import Data.Kind          (Type) import GHC.TypeLits       (KnownNat, Nat, type (+), type (-), type (*),                            type (^), type (<=), natVal)-import GHC.TypeLits.Extra (CLog, FLog, Div, Log, Mod)+import GHC.TypeLits.Extra (CLog, FLog, Div, Log, Mod, Min, Max)+import GHC.Natural        (naturalFromInteger) import Language.Haskell.TH (appT, conT, litT, numTyLit, sigE) import Language.Haskell.TH.Syntax (Lift (..))+import Numeric.Natural    (Natural) import Unsafe.Coerce      (unsafeCoerce) import Clash.XException   (ShowX (..), showsPrecXWith) @@ -102,7 +109,7 @@ snatProxy _ = SNat  instance Show (SNat n) where-  show p@SNat = 'd' : show (natVal p)+  show p@SNat = 'd' : show (snatToInteger p)  instance ShowX (SNat n) where   showsPrecX = showsPrecXWith showsPrec@@ -112,20 +119,25 @@ withSNat :: KnownNat n => (SNat n -> a) -> a withSNat f = f SNat -{-# INLINE snatToInteger #-} -- | Reify the type-level 'Nat' @n@ to it's term-level 'Integer' representation. snatToInteger :: SNat n -> Integer snatToInteger p@SNat = natVal p+{-# INLINE snatToInteger #-} +snatToNatural :: SNat n -> Natural+snatToNatural = naturalFromInteger . snatToInteger+{-# INLINE snatToNatural #-}++ -- | Reify the type-level 'Nat' @n@ to it's term-level 'Num'ber.-snatToNum :: Num a => SNat n -> a-snatToNum p@SNat = fromInteger (natVal p)+snatToNum :: forall a n . Num a => SNat n -> a+snatToNum p@SNat = fromInteger (snatToInteger p) {-# INLINE snatToNum #-}  -- | Unary representation of a type-level natural ----- __NB__: Not synthesisable-data UNat :: Nat -> * where+-- __NB__: Not synthesizable+data UNat :: Nat -> Type where   UZero :: UNat 0   USucc :: UNat n -> UNat (n + 1) @@ -137,24 +149,24 @@  -- | Convert a singleton natural number to its unary representation ----- __NB__: Not synthesisable-toUNat :: SNat n -> UNat n-toUNat p@SNat = fromI (natVal p)+-- __NB__: Not synthesizable+toUNat :: forall n . SNat n -> UNat n+toUNat p@SNat = fromI @n (snatToInteger p)   where-    fromI :: Integer -> UNat m-    fromI 0 = unsafeCoerce UZero-    fromI n = unsafeCoerce (USucc (fromI (n - 1)))+    fromI :: forall m . Integer -> UNat m+    fromI 0 = unsafeCoerce @(UNat 0) @(UNat m) UZero+    fromI n = unsafeCoerce @(UNat ((m-1)+1)) @(UNat m) (USucc (fromI @(m-1) (n - 1)))  -- | Convert a unary-encoded natural number to its singleton representation ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable fromUNat :: UNat n -> SNat n fromUNat UZero     = SNat :: SNat 0 fromUNat (USucc x) = addSNat (fromUNat x) (SNat :: SNat 1)  -- | Add two unary-encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable addUNat :: UNat n -> UNat m -> UNat (n + m) addUNat UZero     y     = y addUNat x         UZero = x@@ -162,7 +174,7 @@  -- | Multiply two unary-encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable mulUNat :: UNat n -> UNat m -> UNat (n * m) mulUNat UZero      _     = UZero mulUNat _          UZero = UZero@@ -170,25 +182,37 @@  -- | Power of two unary-encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable powUNat :: UNat n -> UNat m -> UNat (n ^ m) powUNat _ UZero     = USucc UZero powUNat x (USucc y) = mulUNat x (powUNat x y)  -- | Predecessor of a unary-encoded natural number ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable predUNat :: UNat (n+1) -> UNat n predUNat (USucc x) = x+predUNat UZero     =+  error "predUNat: impossible: 0 minus 1, -1 is not a natural number"  -- | Subtract two unary-encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable subUNat :: UNat (m+n) -> UNat n -> UNat m subUNat x         UZero     = x subUNat (USucc x) (USucc y) = subUNat x y-subUNat UZero     _         = error "impossible: 0 + (n + 1) ~ 0"+subUNat UZero     _         = error "subUNat: impossible: 0 + (n + 1) ~ 0" +-- | Predecessor of a singleton natural number+predSNat :: SNat (a+1) -> SNat (a)+predSNat SNat = SNat+{-# INLINE predSNat #-}++-- | Successor of a singleton natural number+succSNat :: SNat a -> SNat (a+1)+succSNat SNat = SNat+{-# INLINE succSNat #-}+ -- | Add two singleton natural numbers addSNat :: SNat a -> SNat b -> SNat (a+b) addSNat SNat SNat = SNat@@ -225,6 +249,12 @@ {-# INLINE modSNat #-} infixl 7 `modSNat` +minSNat :: SNat a -> SNat b -> SNat (Min a b)+minSNat SNat SNat = SNat++maxSNat :: SNat a -> SNat b -> SNat (Max a b)+maxSNat SNat SNat = SNat+ -- | Floor of the logarithm of a natural number flogBaseSNat :: (2 <= base, 1 <= x)              => SNat base -- ^ Base@@ -256,10 +286,22 @@ pow2SNat SNat = SNat {-# INLINE pow2SNat #-} +-- | Ordering relation between two Nats+data SNatLE a b where+  SNatLE :: forall a b . a <= b => SNatLE a b+  SNatGT :: forall a b . (b+1) <= a => SNatLE a b++-- | Get an ordering relation between two SNats+compareSNat :: forall a b . SNat a -> SNat b -> SNatLE a b+compareSNat a b =+  if snatToInteger a <= snatToInteger b+     then unsafeCoerce (SNatLE @0 @0)+     else unsafeCoerce (SNatGT @1 @0)+ -- | Base-2 encoded natural number -- --    * __NB__: The LSB is the left/outer-most constructor:---    * __NB__: Not synthesisable+--    * __NB__: Not synthesizable -- -- >>> B0 (B1 (B1 BT)) -- b6@@ -283,7 +325,7 @@ --      @ --      __B1__ :: 'BNat' n -> 'BNat' ((2 '*' n) '+' 1) --      @-data BNat :: Nat -> * where+data BNat :: Nat -> Type where   BT :: BNat 0   B0 :: BNat n -> BNat (2*n)   B1 :: BNat n -> BNat ((2*n) + 1)@@ -316,9 +358,9 @@  -- | Convert a singleton natural number to its base-2 representation ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable toBNat :: SNat n -> BNat n-toBNat s@SNat = toBNat' (natVal s)+toBNat s@SNat = toBNat' (snatToInteger s)   where     toBNat' :: Integer -> BNat m     toBNat' 0 = unsafeCoerce BT@@ -328,7 +370,7 @@  -- | Convert a base-2 encoded natural number to its singleton representation ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable fromBNat :: BNat n -> SNat n fromBNat BT     = SNat :: SNat 0 fromBNat (B0 x) = mulSNat (SNat :: SNat 2) (fromBNat x)@@ -337,7 +379,7 @@  -- | Add two base-2 encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable addBNat :: BNat n -> BNat m -> BNat (n+m) addBNat (B0 a) (B0 b) = B0 (addBNat a b) addBNat (B0 a) (B1 b) = B1 (addBNat a b)@@ -348,7 +390,7 @@  -- | Multiply two base-2 encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable mulBNat :: BNat n -> BNat m -> BNat (n*m) mulBNat BT      _  = BT mulBNat _       BT = BT@@ -357,7 +399,7 @@  -- | Power of two base-2 encoded natural numbers ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable powBNat :: BNat n -> BNat m -> BNat (n^m) powBNat _  BT      = B1 BT powBNat a  (B0 b)  = let z = powBNat a b@@ -367,7 +409,7 @@  -- | Successor of a base-2 encoded natural number ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable succBNat :: BNat n -> BNat (n+1) succBNat BT     = B1 BT succBNat (B0 a) = B1 a@@ -375,7 +417,7 @@  -- | Predecessor of a base-2 encoded natural number ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable predBNat :: (1 <= n) => BNat n -> BNat (n-1) predBNat (B1 a) = case stripZeros a of   BT -> BT@@ -384,26 +426,27 @@  -- | Divide a base-2 encoded natural number by 2 ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable div2BNat :: BNat (2*n) -> BNat n div2BNat BT     = BT div2BNat (B0 x) = x-div2BNat (B1 _) = error "impossible: 2*n ~ 2*n+1"+div2BNat (B1 _) = error "div2BNat: impossible: 2*n ~ 2*n+1"  -- | Subtract 1 and divide a base-2 encoded natural number by 2 ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable div2Sub1BNat :: BNat (2*n+1) -> BNat n div2Sub1BNat (B1 x) = x-div2Sub1BNat _      = error "impossible: 2*n+1 ~ 2*n"+div2Sub1BNat _      = error "div2Sub1BNat: impossible: 2*n+1 ~ 2*n"  -- | Get the log2 of a base-2 encoded natural number ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable log2BNat :: BNat (2^n) -> BNat n+log2BNat BT = error "log2BNat: log2(0) not defined" log2BNat (B1 x) = case stripZeros x of   BT -> BT-  _  -> error "impossible: 2^n ~ 2x+1"+  _  -> error "log2BNat: impossible: 2^n ~ 2x+1" log2BNat (B0 x) = succBNat (log2BNat x)  -- | Strip non-contributing zero's from a base-2 encoded natural number@@ -417,7 +460,7 @@ -- >>> stripZeros (B1 (B0 (B0 (B0 BT)))) -- b1 ----- __NB__: Not synthesisable+-- __NB__: Not synthesizable stripZeros :: BNat n -> BNat n stripZeros BT      = BT stripZeros (B1 x)  = B1 (stripZeros x)@@ -426,11 +469,9 @@   BT -> BT   k  -> B0 k --- | Change a function that has an argument with an @(n + k)@ constraint to a+-- | Change a function that has an argument with an @(n ~ (k + m))@ constraint to a -- function with an argument that has an @(k <= n)@ constraint. ----- __NB__ It is the dual to 'plusToLe'--- -- === __Examples__ -- -- Example 1@@ -438,86 +479,37 @@ -- @ -- f :: Index (n+1) -> Index (n + 1) -> Bool ----- g :: (1 '<=' n) => Index n -> Index n -> Bool--- g a b = 'leToPlus' \@1 $ \\a' -> 'leToPlus' \@1 $ \\b' -> f a' b'+-- g :: forall n. (1 '<=' n) => Index n -> Index n -> Bool+-- g a b = 'leToPlus' \@1 \@n (f a b) -- @ -- -- Example 2 -- -- @--- import Data.Bifunctor.Flip--- -- head :: Vec (n + 1) a -> a ----- head' :: (1 '<=' n) => Vec n a -> a--- head' a = 'leToPlus' \@1 (Flip a) (head . runFlip)+-- head' :: forall n a. (1 '<=' n) => Vec n a -> a+-- head' = 'leToPlus' @1 @n head -- @ leToPlus-  :: forall (k :: Nat) (n :: Nat) f r-   . (k <= n)-  => f n-  -- ^ Argument with the @(k <= n)@ constraint-  -> (forall m . f (m + k) -> r)-  -- ^ Function with the @(n + k)@ constraint+  :: forall (k :: Nat) (n :: Nat) r+   . ( k <= n+     )+  => (forall m . (n ~ (k + m)) => r)+  -- ^ Context with the @(n ~ (k + m))@ constraint   -> r-leToPlus a f = f @ (n-k) a+leToPlus r = r @(n - k) {-# INLINE leToPlus #-}  -- | Same as 'leToPlus' with added 'KnownNat' constraints leToPlusKN-  :: forall (k :: Nat) (n :: Nat) f r-   . (k <= n, KnownNat n, KnownNat k)-  => f n-  -- ^ Argument with the @(k <= n)@ constraint-  -> (forall m . KnownNat m => f (m + k) -> r)-  -- ^ Function with the @(n + k)@ constraint+  :: forall (k :: Nat) (n :: Nat) r+   . ( k <= n+     , KnownNat k+     , KnownNat n+     )+  => (forall m . (n ~ (k + m), KnownNat m) => r)+  -- ^ Context with the @(n ~ (k + m))@ constraint   -> r-leToPlusKN a f = f @ (n-k) a+leToPlusKN r = r @(n - k) {-# INLINE leToPlusKN #-}---- | Change a function that has an argument with an @(k <= n)@ constraint to a--- function with an argument that has an @(n + k)@ constraint.------ __NB__ It is the dual to 'leToPlus'------ === __Examples__------ Example 1------ @--- f :: (1 '<=' n) => Index n -> Index n -> Bool------ g :: Index (n + 1) -> Index (n + 1) -> Bool--- g a b = 'plusToLe' \@1 $ \\a' -> 'plusToLe' \@1 $ \\b' -> f a' b'--- @------ Example 2------ @--- import Datal.Bifunctor.Flip------ fold :: (1 '<=' n) => (a -> a -> a) -> Vec n a -> a------ fold' :: (a -> a -> a) -> Vec (n+1) a -> a--- fold' f a = 'plusToLe' \@1 (Flip a) (fold f . runFlip)--- @-plusToLe-  :: forall (k :: Nat) n f r-   . f (n + k)-  -- ^ Argument with the @(n + k)@ constraint-  -> (forall m . (k <= m) => f m -> r)-  -- ^ Function with the @(k <= n)@ constraint-  -> r-plusToLe a f = f @(n + k) a-{-# INLINE plusToLe #-}---- | Same as 'plusToLe' with added 'KnownNat' constraints-plusToLeKN-  :: forall (k :: Nat) n f r-   . (KnownNat n, KnownNat k)-  => f (n + k)-  -- ^ Argument with the @(n + k)@ constraint-  -> (forall m . (KnownNat m, k <= m) => f m -> r)-  -- ^ Function with the @(k <= n)@ constraint-  -> r-plusToLeKN a f = f @(n + k) a
src/Clash/Promoted/Nat/Literals.hs view
@@ -18,15 +18,21 @@ You can generate more 'SNat' literals using 'decLiteralsD' from "Clash.Promoted.Nat.TH" -} +{-# LANGUAGE CPP             #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DataKinds       #-}  {-# LANGUAGE Trustworthy #-} -{-# OPTIONS_HADDOCK show-extensions #-}+{-# OPTIONS_HADDOCK show-extensions, prune #-}  module Clash.Promoted.Nat.Literals where  import Clash.Promoted.Nat.TH +#ifdef HADDOCK_ONLY+-- Don't pollute docs with 1024 SNat literals+$(decLiteralsD 0 9)+#else $(decLiteralsD 0 1024)+#endif
src/Clash/Promoted/Symbol.hs view
@@ -4,9 +4,10 @@ Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE DataKinds      #-}-{-# LANGUAGE GADTs          #-}-{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE KindSignatures        #-}+{-# LANGUAGE TemplateHaskellQuotes #-}  {-# LANGUAGE Safe #-} @@ -16,11 +17,19 @@   (SSymbol (..), ssymbolProxy, ssymbolToString) where +import Language.Haskell.TH.Syntax import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)  -- | Singleton value for a type-level string @s@ data SSymbol (s :: Symbol) where   SSymbol :: KnownSymbol s => SSymbol s++instance KnownSymbol s => Lift (SSymbol (s :: Symbol)) where+--  lift :: t -> Q Exp+  lift t = pure (AppTypeE (ConE 'SSymbol) tt)+    where+      tt = LitT (StrTyLit (ssymbolToString t))+  instance Show (SSymbol s) where   show s@SSymbol = symbolVal s
src/Clash/Signal.hs view
@@ -1,768 +1,1876 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2016     , Myrtle Software,-                  2017     , Google Inc.-License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>--CλaSH has synchronous 'Signal's in the form of:--@-'Signal' (domain :: 'Domain') a-@--Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,-and /domain/ is the /clock-/ (and /reset-/) domain to which the memory elements-manipulating these 'Signal's belong.--The type-parameter, /domain/, is of the kind 'Domain' which has types of the-following shape:--@-data Domain = Dom { domainName :: 'GHC.TypeLits.Symbol', clkPeriod :: 'GHC.TypeLits.Nat' }-@--Where /domainName/ is a type-level string ('GHC.TypeLits.Symbol') representing-the name of the /clock-/ (and /reset-/) domain, and /clkPeriod/ is a type-level-natural number ('GHC.TypeLits.Nat') representing the clock period (in __ps__)-of the clock lines in the /clock-domain/.--* __NB__: \"Bad things\"™  happen when you actually use a clock period of @0@,-so do __not__ do that!-* __NB__: You should be judicious using a clock with period of @1@ as you can-never create a clock that goes any faster!--}--{-# LANGUAGE ConstraintKinds     #-}-{-# LANGUAGE DataKinds           #-}-{-# LANGUAGE FlexibleContexts    #-}-{-# LANGUAGE GADTs               #-}-{-# LANGUAGE MagicHash           #-}-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE RebindableSyntax    #-}-{-# LANGUAGE OverloadedLabels    #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications    #-}--{-# LANGUAGE Trustworthy #-}--{-# OPTIONS_GHC -fno-warn-unused-imports #-}-{-# OPTIONS_HADDOCK show-extensions #-}--module Clash.Signal-  ( -- * Synchronous signals-    Signal-  , Domain (..)-  , System-    -- * Clock-  , Clock-  , ClockKind (..)-    -- * Reset-  , Reset-  , ResetKind (..)-  , unsafeFromAsyncReset-  , unsafeToAsyncReset-  , fromSyncReset-  , unsafeToSyncReset-  , resetSynchronizer-    -- * Hidden clocks and resets-    -- $hiddenclockandreset--    -- ** Hidden clock-  , HiddenClock-  , hideClock-  , exposeClock-  , withClock-  , hasClock-    -- ** Hidden reset-  , HiddenReset-  , hideReset-  , exposeReset-  , withReset-  , hasReset-    -- ** Hidden clock and reset-  , HiddenClockReset-  , hideClockReset-  , exposeClockReset-  , withClockReset-  , SystemClockReset-    -- * Basic circuit functions-  , delay-  , register-  , regMaybe-  , regEn-  , mux-    -- * Simulation and testbench functions-  , clockGen-  , tbClockGen-  , asyncResetGen-  , syncResetGen-  , systemClockGen-  , tbSystemClockGen-  , systemResetGen-    -- * Boolean connectives-  , (.&&.), (.||.)-    -- * Product/Signal isomorphism-  , Bundle(..)-    -- * Simulation functions (not synthesisable)-  , simulate-  , simulateB-    -- ** lazy versions-  , simulate_lazy-  , simulateB_lazy-    -- * List \<-\> Signal conversion (not synthesisable)-  , sample-  , sampleN-  , fromList-    -- ** lazy versions-  , sample_lazy-  , sampleN_lazy-  , fromList_lazy-    -- * QuickCheck combinators-  , testFor-    -- * Type classes-    -- ** 'Eq'-like-  , (.==.), (./=.)-    -- ** 'Ord'-like-  , (.<.), (.<=.), (.>=.), (.>.)-  )-where--import           Control.DeepSeq       (NFData)-import           GHC.Stack             (HasCallStack, withFrozenCallStack)-import           GHC.TypeLits          (KnownNat, KnownSymbol)-import           Data.Bits             (Bits) -- Haddock only-import           Data.Maybe            (isJust, fromJust)-import           Prelude-import           Test.QuickCheck       (Property, property)-import           Unsafe.Coerce         (unsafeCoerce)--import           Clash.Explicit.Signal-  (System, resetSynchronizer, systemClockGen, systemResetGen, tbSystemClockGen)-import qualified Clash.Explicit.Signal as S-import           Clash.Hidden-import           Clash.Promoted.Nat    (SNat (..))-import           Clash.Promoted.Symbol (SSymbol (..))-import           Clash.Signal.Bundle   (Bundle (..))-import           Clash.Signal.Internal hiding-  (sample, sample_lazy, sampleN, sampleN_lazy, simulate, simulate_lazy, testFor)-import qualified Clash.Signal.Internal as S--{- $setup->>> :set -XFlexibleContexts -XTypeApplications->>> import Clash.XException (printX)->>> import Control.Applicative (liftA2)->>> let oscillate = register False (not <$> oscillate)->>> let count = regEn 0 oscillate (count + 1)->>> :{-sometimes1 = s where-  s = register Nothing (switch <$> s)-  switch Nothing = Just 1-  switch _       = Nothing-:}-->>> :{-countSometimes = s where-  s     = regMaybe 0 (plusM (pure <$> s) sometimes1)-  plusM = liftA2 (liftA2 (+))-:}---}---- * Hidden clock and reset arguments--{- $hiddenclockandreset #hiddenclockandreset#-Clocks and resets are by default implicitly routed to their components. You can-see from the type of a component whether it has hidden clock or reset-arguments:--It has a hidden clock when it has a:--@-f :: 'HiddenClock' domain gated => ...-@--Constraint.--Or it has a hidden reset when it has a:--@-g :: 'HiddenReset' domain synchronous => ...-@--Constraint.--Or it has both a hidden clock argument and a hidden reset argument when it-has a:--@-h :: 'HiddenClockReset' domain gated synchronous => ..-@--Constraint.--Given a component with an explicit clock and reset arguments, you can turn them-into hidden arguments using 'hideClock' and 'hideReset'. So given a:--@-f :: Clock domain gated -> Reset domain synchronous -> Signal domain a -> ...-@--You hide the clock and reset arguments by:--@--- g :: 'HiddenClockReset' domain gated synchronous => Signal domain a -> ...-g = 'hideClockReset' f-@--Or, alternatively, by:--@--- h :: HiddenClockReset domain gated synchronous => Signal domain a -> ...-h = f 'hasClock' 'hasReset'-@--=== Assigning explicit clock and reset arguments to hidden clocks and resets--Given a component:--@-f :: HiddenClockReset domain gated synchronous-  => Signal domain Int-  -> Signal domain Int-@--which has hidden clock and routed reset arguments, we expose those hidden-arguments so that we can explicitly apply them:--@--- g :: Clock domain gated -> Reset domain synchronous -> Signal domain Int -> Signal domain Int-g = 'exposeClockReset' f-@--or, alternatively, by:--@--- h :: Clock domain gated -> Reset domain synchronous -> Signal domain Int -> Signal domain Int-h clk rst = withClock clk rst f-@--Similarly, there are 'exposeClock' and 'exposeReset' to connect just expose-the hidden clock or the hidden reset argument.--You will need to explicitly apply clocks and resets when you want to use-components such as PPLs and 'resetSynchronizer':--@-topEntity-  :: Clock System Source-  -> Reset System Asynchronous-  -> Signal System Int-  -> Signal System Int-topEntity clk rst =-  let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst-      rstSync            = 'resetSynchronizer' pllOut ('unsafeToAsyncReset' pllStable)-  in  'exposeClockReset' f pllOut rstSync-@--or, using the alternative method:--@-topEntity2-  :: Clock System Source-  -> Reset System Asynchronous-  -> Signal System Int-  -> Signal System Int-topEntity2 clk rst =-  let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst-      rstSync            = 'resetSynchronizer' pllOut ('unsafeToAsyncReset' pllStable)-  in  'withClockReset' pllOut rstSync f-@---}---- | A /constraint/ that indicates the component has a hidden 'Clock'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-type HiddenClock domain gated = Hidden "clk" (Clock domain gated)---- | A /constraint/ that indicates the component needs a 'Reset'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-type HiddenReset domain synchronous = Hidden "rst" (Reset domain synchronous)---- | A /constraint/ that indicates the component needs a 'Clock' and 'Reset'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-type HiddenClockReset domain gated synchronous =-  (HiddenClock domain gated, HiddenReset domain synchronous)---- | A /constraint/ that indicates the component needs a 'Clock' and a 'Reset'--- belonging to the 'System' domain.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-type SystemClockReset = HiddenClockReset System 'Source 'Asynchronous---- | Expose the hidden 'Clock' argument of a component, so it can be applied--- explicitly------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-exposeClock-  :: (HiddenClock domain gated => r)-  -- ^ The component with a hidden clock-  -> (Clock domain gated -> r)-  -- ^ The component with its clock argument exposed-exposeClock = \f clk -> expose @"clk" f clk-{-# INLINE exposeClock #-}---- | Hide the 'Clock' argument of a component, so it can be routed implicitly.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-hideClock-  :: HiddenClock domain gated-  => (Clock domain gated -> r)-  -- ^ Function whose clock argument you want to hide-  -> r-hideClock = \f -> f #clk-{-# INLINE hideClock #-}---- | Connect an explicit 'Clock' to a function with a hidden 'Clock' argument.------ @--- withClock = 'flip' exposeClock--- @-withClock-  :: Clock domain gated-  -- ^ The 'Clock' we want to connect-  -> (HiddenClock domain gated => r)-  -- ^ The function with a hidden 'Clock' argument-  -> r-withClock = \clk f -> expose @"clk" f clk-{-# INLINE withClock #-}---- | Connect a hidden 'Clock' to an argument where a normal 'Clock' argument--- was expected.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-hasClock-  :: HiddenClock domain gated-  => Clock domain gated-hasClock = #clk-{-# INLINE hasClock #-}---- | Expose the hidden 'Reset' argument of a component, so it can be applied--- explicitly------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-exposeReset-  :: (HiddenReset domain synchronous => r)-  -- ^ The component with a hidden reset-  -> (Reset domain synchronous -> r)-  -- ^ The component with its reset argument exposed-exposeReset = \f rst -> expose @"rst" f rst-{-# INLINE exposeReset #-}---- | Hide the 'Reset' argument of a component, so it can be routed implicitly.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-hideReset-  :: HiddenReset domain synchronous-  => (Reset domain synchronous -> r)-  -- ^ Component whose reset argument you want to hide-  -> r-hideReset = \f -> f #rst-{-# INLINE hideReset #-}---- | Connect an explicit 'Reset' to a function with a hidden 'Reset' argument.------ @--- withReset = 'flip' exposeReset--- @------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-withReset-  :: Reset domain synchronous-  -- ^ The 'Reset' we want to connect-  -> (HiddenReset domain synchronous => r)-  -- ^ The function with a hidden 'Reset' argument-  -> r-withReset = \rst f -> expose @"rst" f rst-{-# INLINE withReset #-}---- | Connect a hidden 'Reset' to an argument where a normal 'Reset' argument--- was expected.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-hasReset-  :: HiddenReset domain synchronous-  => Reset domain synchronous-hasReset = #rst-{-# INLINE hasReset #-}---- | Expose the hidden 'Clock' and 'Reset' arguments of a component, so they can--- be applied explicitly------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>------ === __Example__------ @--- topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)--- topEntity = concat------ testBench :: Signal System Bool--- testBench = done---   where---     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)---     expectedOutput = outputVerifier ((1:>2:>3:>4:>5:>6:>Nil):>Nil)---     done           = exposeClockReset (expectedOutput (topEntity <$> testInput)) clk rst---     clk            = tbSystemClockGen (not <\$\> done)---     rst            = systemResetGen--- @-exposeClockReset-  :: (HiddenClockReset domain gated synchronous => r)-  -- ^ The component with hidden clock and reset arguments-  -> (Clock domain gated -> Reset domain synchronous -> r)-  -- ^ The component with its clock and reset arguments exposed-exposeClockReset = \f clk rst -> expose @"rst" (expose @"clk" f clk) rst-{-# INLINE exposeClockReset #-}---- -- | Hide the 'Clock' and 'Reset' arguments of a component, so they can be--- -- routed implicitly------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-hideClockReset-  :: HiddenClockReset domain gated synchronous-  => (Clock domain gated -> Reset domain synchronous -> r)-  -- ^ Component whose clock and reset argument you want to hide-  -> r-hideClockReset = \f -> f #clk #rst-{-# INLINE hideClockReset #-}---- | Connect an explicit 'Clock' and 'Reset' to a function with a hidden--- 'Clock' and 'Reset' argument.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks and resets>-withClockReset-  :: Clock domain gated-  -- ^ The 'Clock' we want to connect-  -> Reset domain synchronous-  -- ^ The 'Reset' we want to connect-  -> (HiddenClockReset domain gated synchronous => r)-  -- ^ The function with a hidden 'Clock' and hidden 'Reset' argument-  -> r-withClockReset = \clk rst f -> expose @"rst" (expose @"clk" f clk) rst-{-# INLINE withClockReset #-}---- * Basic circuit functions---- | 'delay' @s@ delays the values in 'Signal' @s@ for once cycle, the value--- at time 0 is undefined.------ >>> printX (sampleN 3 (delay (fromList [1,2,3,4])))--- [X,1,2]-delay-  :: (HiddenClock domain gated, HasCallStack)-  => Signal domain a-  -- ^ Signal to delay-  -> Signal domain a-delay = \i -> withFrozenCallStack (delay# #clk i)-{-# INLINE delay #-}---- | 'register' @i s@ delays the values in 'Signal' @s@ for one cycle, and sets--- the value at time 0 to @i@------ >>> sampleN 3 (register 8 (fromList [1,2,3,4]))--- [8,1,2]-register-  :: (HiddenClockReset domain gated synchronous, HasCallStack)-  => a-  -- ^ Reset value-  ---  -- 'register' has an /active-hig/h 'Reset', meaning that 'register' outputs the-  -- reset value when the reset value becomes 'True'-  -> Signal domain a-  -> Signal domain a-register = \i s -> withFrozenCallStack (register# #clk #rst i s)-{-# INLINE register #-}-infixr 3 `register`---- | Version of 'register' that only updates its content when its second--- argument is a 'Just' value. So given:------ @--- sometimes1 = s where---   s = 'register' Nothing (switch '<$>' s)------   switch Nothing = Just 1---   switch _       = Nothing------ countSometimes = s where---   s     = 'regMaybe' 0 (plusM ('pure' '<$>' s) sometimes1)---   plusM = 'liftA2' (liftA2 (+))--- @------ We get:------ >>> sampleN 8 sometimes1--- [Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]--- >>> sampleN 8 countSometimes--- [0,0,1,1,2,2,3,3]-regMaybe-  :: (HiddenClockReset domain gated synchronous, HasCallStack)-  => a-  -- ^ Reset value-  ---  -- 'regMaybe' has an /active-high/ 'Reset', meaning that 'regMaybe' outputs the-  -- reset value when the reset value becomes 'True'-  -> Signal domain (Maybe a)-  -> Signal domain a-regMaybe = \initial iM -> withFrozenCallStack-  (register# (clockGate #clk (fmap isJust iM)) #rst initial (fmap fromJust iM))-{-# INLINE regMaybe #-}-infixr 3 `regMaybe`---- | Version of 'register' that only updates its content when its second argument--- is asserted. So given:------ @--- oscillate = 'register' False ('not' '<$>' oscillate)--- count     = 'regEn' 0 oscillate (count + 1)--- @------ We get:------ >>> sampleN 8 oscillate--- [False,True,False,True,False,True,False,True]--- >>> sampleN 8 count--- [0,0,1,1,2,2,3,3]-regEn-  :: (HiddenClockReset domain gated synchronous, HasCallStack)-  => a-  -- ^ Reset value-  ---  -- 'regEn' has an /active-high/ 'Reset', meaning that 'regEn' outputs the-  -- reset value when the reset value becomes 'True'-  -> Signal domain Bool-  -> Signal domain a-  -> Signal domain a-regEn = \initial en i -> withFrozenCallStack-  (register# (clockGate #clk en) #rst initial i)-{-# INLINE regEn #-}---- * Signal -> List conversion---- | Get an infinite list of samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ __NB__: This function is not synthesisable-sample-  :: forall gated synchronous domain a-   . NFData a-  => (HiddenClockReset domain gated synchronous => Signal domain a)-  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock-  -- (and reset)-  -> [a]-sample s =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.sample (exposeClockReset s clk rst)---- | Get a list of /n/ samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sampleN 3 s == [s0, s1, s2]------ __NB__: This function is not synthesisable-sampleN-  :: forall gated synchronous domain a-   . NFData a-  => Int-  -- ^ The number of samples we want to see-  -> (HiddenClockReset domain gated synchronous => Signal domain a)-  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock-  -- (and reset)-  -> [a]-sampleN n s =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.sampleN n (exposeClockReset s clk rst)---- | /Lazily/ get an infinite list of samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ __NB__: This function is not synthesisable-sample_lazy-  :: forall gated synchronous domain a-   . (HiddenClockReset domain gated synchronous => Signal domain a)-  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock-  -- (and reset)-  -> [a]-sample_lazy s =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.sample_lazy (exposeClockReset s clk rst)----- | Lazily get a list of /n/ samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sampleN 3 s == [s0, s1, s2]------ __NB__: This function is not synthesisable-sampleN_lazy-  :: forall gated synchronous domain a-   . Int-  -> (HiddenClockReset domain gated synchronous => Signal domain a)-  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock-  -- (and reset)-  -> [a]-sampleN_lazy n s =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.sampleN_lazy n (exposeClockReset s clk rst)---- * Simulation functions---- | Simulate a (@'Signal' a -> 'Signal' b@) function given a list of samples--- of type /a/------ >>> simulate (register 8) [1, 2, 3]--- [8,1,2,3...--- ...------ __NB__: This function is not synthesisable-simulate-  :: forall gated synchronous domain a b-   . (NFData a, NFData b)-  => (HiddenClockReset domain gated synchronous =>-      Signal domain a -> Signal domain b)-  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock-  -- (and reset)-  -> [a]-  -> [b]-simulate f =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.simulate (exposeClockReset f clk rst)---- | /Lazily/ simulate a (@'Signal' a -> 'Signal' b@) function given a list of--- samples of type /a/------ >>> simulate (register 8) [1, 2, 3]--- [8,1,2,3...--- ...------ __NB__: This function is not synthesisable-simulate_lazy-  :: forall gated synchronous domain a b-   . (HiddenClockReset domain gated synchronous =>-      Signal domain a -> Signal domain b)-  -- ^ Function we want to simulate, whose components potentially have a hidden-  -- clock (and reset)-  -> [a]-  -> [b]-simulate_lazy f =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.simulate_lazy (exposeClockReset f clk rst)---- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of--- samples of type @a@------ >>> simulateB (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...--- ...------ __NB__: This function is not synthesisable-simulateB-  :: forall gated synchronous domain a b-   . (Bundle a, Bundle b, NFData a, NFData b)-  => (HiddenClockReset domain gated synchronous =>-      Unbundled domain a -> Unbundled domain b)-  -- ^ Function we want to simulate, whose components potentially have a hidden-  -- clock (and reset)-  -> [a]-  -> [b]-simulateB f =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.simulateB (exposeClockReset f clk rst)---- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a--- list of samples of type @a@------ >>> simulateB (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...--- ...------ __NB__: This function is not synthesisable-simulateB_lazy-  :: forall gated synchronous domain a b-   . (Bundle a, Bundle b)-  => (HiddenClockReset domain gated synchronous =>-      Unbundled domain a -> Unbundled domain b)-  -- ^ Function we want to simulate, whose components potentially have a hidden-  -- clock (and reset)-  -> [a]-  -> [b]-simulateB_lazy f =-  let clk = unsafeCoerce @(Clock System 'Gated)-                         @(Clock domain gated)-                         (GatedClock @System SSymbol SNat (pure True))-      rst = unsafeCoerce @(Reset System 'Asynchronous)-                         @(Reset domain synchronous)-                         (Async (True :- pure False))-  in  S.simulateB_lazy (exposeClockReset f clk rst)---- * QuickCheck combinators---- |  @testFor n s@ tests the signal /s/ for /n/ cycles.-testFor-  :: Int-  -- ^ The number of cycles we want to test for-  -> (HiddenClockReset domain gated synchronous => Signal domain Bool)-  -- ^ 'Signal' we want to evaluate, whose source potentially has a hidden clock-  -- (and reset)-  -> Property-testFor n s = property (and (Clash.Signal.sampleN n s))+                  2016-2019, Myrtle Software Ltd,+                  2017     , Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++Clash has synchronous 'Signal's in the form of:++@+'Signal' (dom :: 'Domain') a+@++Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,+and /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements+manipulating these 'Signal's belong.++The type-parameter, /dom/, is of the kind 'Domain' - a simple string. That+string refers to a single /synthesis domain/. A synthesis domain describes the+behavior of certain aspects of memory elements in it. More specifically, a+domain looks like:++@+'DomainConfiguration'+  { _name :: 'Domain'+  -- ^ Domain name+  , _period :: 'Nat'+  -- ^ Clock period in /ps/+  , _edge :: 'ActiveEdge'+  -- ^ Active edge of the clock+  , _reset :: 'ResetKind'+  -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)+  , _init :: 'InitBehavior'+  -- ^ Whether the initial (or "power up") value of memory elements is+  -- unknown/undefined, or configurable to a specific value+  , _polarity :: ResetPolarity+  -- ^ Whether resets are active high or active low+  }+@++Check the documentation of each of the types to see the various options Clash+provides. In order to specify a domain, an instance of 'KnownDomain' should be+made. Clash provides an implementation 'System' with some common options+chosen:++@+instance KnownDomain "System" where+  type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh+@++In words, "System" is a synthesis domain with a clock running with a period+of 10000 /ps/. Memory elements respond to the rising edge of the clock,+asynchronously to changes in their resets, and have defined power up values+if applicable.++In order to create a new domain, you don't have to instantiate it explicitly.+Instead, you can have 'createDomain' create a domain for you. You can also use+the same function to subclass existing domains.++* __NB__: \"Bad things\"™  happen when you actually use a clock period of @0@,+so do __not__ do that!+* __NB__: You should be judicious using a clock with period of @1@ as you can+never create a clock that goes any faster!+* __NB__: Whether 'System' has good defaults depends on your target platform.+Check out 'IntelSystem' and 'XilinxSystem' too!+-}++{-# LANGUAGE CPP                   #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE ExplicitNamespaces    #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE KindSignatures        #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeOperators         #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# LANGUAGE Trustworthy #-}++{-# OPTIONS_GHC -fno-warn-unused-imports #-}+{-# OPTIONS_HADDOCK show-extensions #-}++module Clash.Signal+  ( -- * Synchronous signals+    Signal+  , BiSignalIn+  , BiSignalOut+  , BiSignalDefault(..)+    -- * Domain+  , Domain+  , KnownDomain(..)+  , KnownConfiguration+  , ActiveEdge(..)+  , SActiveEdge(..)+  , InitBehavior(..)+  , SInitBehavior(..)+  , ResetKind(..)+  , SResetKind(..)+  , ResetPolarity(..)+  , SResetPolarity(..)+  , DomainConfiguration(..)+  , SDomainConfiguration(..)+  -- ** Configuration type families+  , DomainPeriod+  , DomainActiveEdge+  , DomainResetKind+  , DomainInitBehavior+  , DomainResetPolarity+    -- ** Default domains+  , System+  , XilinxSystem+  , IntelSystem+  , vSystem+  , vIntelSystem+  , vXilinxSystem+    -- ** Domain utilities+  , VDomainConfiguration(..)+  , vDomain+  , createDomain+  , knownVDomain+  , clockPeriod+  , activeEdge+  , resetKind+  , initBehavior+  , resetPolarity+    -- * Clock+  , Clock+  , periodToHz+  , hzToPeriod+#ifdef CLASH_MULTIPLE_HIDDEN+    -- ** Synchronization primitive+  , unsafeSynchronizer+#endif+    -- * Reset+  , Reset(..)+  , unsafeToReset+  , unsafeFromReset+  , unsafeToHighPolarity+  , unsafeToLowPolarity+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+#ifdef CLASH_MULTIPLE_HIDDEN+  , convertReset+#endif+  , E.resetSynchronizer+  , holdReset+    -- ** Enabling+  , Enable(..)+  , toEnable+  , fromEnable+  , S.enableGen+    -- * Hidden clocks and resets+    -- $hiddenclockandreset++    -- ** Hidden clock+  , HiddenClock+  , hideClock+  , exposeClock+  , exposeSpecificClock+  , withClock+  , withSpecificClock+  , hasClock+    -- ** Hidden reset+  , HiddenReset+  , hideReset+  , exposeReset+  , withReset+#ifdef CLASH_MULTIPLE_HIDDEN+  , exposeSpecificReset+  , withSpecificReset+#endif+  , hasReset+    -- ** Hidden enable+  , HiddenEnable+  , hideEnable+  , exposeEnable+  , withEnable+#ifdef CLASH_MULTIPLE_HIDDEN+  , exposeSpecificEnable+  , withSpecificEnable+#endif+  , hasEnable+    -- ** Hidden clock, reset, and enable+  , HiddenClockResetEnable+  , hideClockResetEnable+  , exposeClockResetEnable+  , withClockResetEnable+#ifdef CLASH_MULTIPLE_HIDDEN+  , exposeSpecificClockResetEnable+  , withSpecificClockResetEnable+#endif+  , SystemClockResetEnable+    -- * Basic circuit functions+  , dflipflop+  , delay+  , delayMaybe+  , delayEn+  , register+  , regMaybe+  , regEn+  , mux+    -- * Simulation and testbench functions+  , clockGen+  , resetGen+  , resetGenN+  , systemClockGen+  , systemResetGen+    -- * Boolean connectives+  , (.&&.), (.||.)+    -- * Product/Signal isomorphism+  , Bundle(..)+    -- * Simulation functions (not synthesizable)+  , simulate+  , simulateB+  , simulateN+  , simulateWithReset+  , simulateWithResetN+    -- ** lazy versions+  , simulate_lazy+  , simulateB_lazy+    -- * List \<-\> Signal conversion (not synthesizable)+  , sample+  , sampleN+  , sampleWithReset+  , sampleWithResetN+  , fromList+  , fromListWithReset+    -- ** lazy versions+  , sample_lazy+  , sampleN_lazy+  , fromList_lazy+    -- * QuickCheck combinators+  , testFor+    -- * Type classes+    -- ** 'Eq'-like+  , (.==.), (./=.)+    -- ** 'Ord'-like+  , (.<.), (.<=.), (.>=.), (.>.)+    -- * Bisignal functions+  , veryUnsafeToBiSignalIn+  , readFromBiSignal+  , writeToBiSignal+  , mergeBiSignalOuts+  )+where++import           GHC.TypeLits+  (KnownNat, KnownSymbol, AppendSymbol, Symbol, type (<=))+import           Data.Bits             (Bits) -- Haddock only+import           Data.Proxy            (Proxy(..))+import           Prelude+import           Test.QuickCheck       (Property, property)++#ifdef CLASH_MULTIPLE_HIDDEN+import           Clash.Class.HasDomain (WithSingleDomain, WithSpecificDomain)+#else+import           Clash.Class.HasDomain (WithSpecificDomain)+#endif+import qualified Clash.Explicit.Signal as E+import           Clash.Explicit.Signal+  (System, resetSynchronizer, systemClockGen, systemResetGen)+import qualified Clash.Explicit.Signal as S+import           Clash.Hidden+import           Clash.Promoted.Nat    (SNat (..), snatToNum)+import           Clash.Promoted.Symbol (SSymbol (..))+import           Clash.Signal.Bundle   (Bundle (..))+import           Clash.Signal.BiSignal --(BisignalIn, BisignalOut, )+import           Clash.Signal.Internal hiding+  (sample, sample_lazy, sampleN, sampleN_lazy, simulate, simulate_lazy, testFor)+import           Clash.Signal.Internal.Ambiguous+  (knownVDomain, clockPeriod, activeEdge, resetKind, initBehavior, resetPolarity)+import qualified Clash.Signal.Internal as S+import           Clash.XException      (NFDataX)++{- $setup+>>> :set -XFlexibleContexts -XTypeApplications+>>> import Clash.Promoted.Nat (SNat(..))+>>> import Clash.XException (printX)+>>> import Control.Applicative (liftA2)+>>> let oscillate = register False (not <$> oscillate)+>>> let count = regEn 0 oscillate (count + 1)+>>> :{+sometimes1 = s where+  s = register Nothing (switch <$> s)+  switch Nothing = Just 1+  switch _       = Nothing+:}++>>> :{+countSometimes = s where+  s     = regMaybe 0 (plusM (pure <$> s) sometimes1)+  plusM = liftA2 (liftA2 (+))+:}++-}++-- * Hidden clock and reset arguments++{- $hiddenclockandreset #hiddenclockandreset#+Clocks and resets are by default implicitly routed to their components. You can+see from the type of a component whether it has hidden clock or reset+arguments:++It has a hidden clock when it has a:++@+f :: 'HiddenClock' dom => ...+@++Constraint.++Or it has a hidden reset when it has a:++@+g :: 'HiddenReset' dom polarity => ...+@++Constraint.++Or it has both a hidden clock argument and a hidden reset argument when it+has a:++@+h :: 'HiddenClockReset' dom  => ..+@++Constraint.++Given a component with an explicit clock and reset arguments, you can turn them+into hidden arguments using 'hideClock' and 'hideReset'. So given a:++@+f :: Clock dom -> Reset dom -> Signal dom a -> ...+@++You hide the clock and reset arguments by:++@+-- g :: 'HiddenClockReset' dom  => Signal dom a -> ...+g = 'hideClockReset' f+@++Or, alternatively, by:++@+-- h :: HiddenClockResetEnable dom  => Signal dom a -> ...+h = f 'hasClock' 'hasReset'+@++=== Assigning explicit clock and reset arguments to hidden clocks and resets++Given a component:++@+f :: HiddenClockResetEnable dom+  => Signal dom Int+  -> Signal dom Int+@++which has hidden clock and routed reset arguments, we expose those hidden+arguments so that we can explicitly apply them:++@+-- g :: Clock dom -> Reset dom -> Signal dom Int -> Signal dom Int+g = 'exposeClockResetEnable' f+@++or, alternatively, by:++@+-- h :: Clock dom -> Reset dom -> Signal dom Int -> Signal dom Int+h clk rst = withClock clk rst f+@++Similarly, there are 'exposeClock' and 'exposeReset' to connect just expose+the hidden clock or the hidden reset argument.++You will need to explicitly apply clocks and resets when you want to use+components such as PPLs and 'resetSynchronizer':++@+topEntity+  :: Clock System+  -> Reset System+  -> Enable System+  -> Signal System Int+  -> Signal System Int+topEntity clk rst =+  let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst+      rstSync            = 'resetSynchronizer' pllOut ('unsafeToAsyncReset' pllStable)+  in  'exposeClockResetEnable' f pllOut rstSync+@++or, using the alternative method:++@+topEntity2+  :: Clock System+  -> Reset System+  -> Signal System Int+  -> Signal System Int+topEntity2 clk rst =+  let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst+      rstSync            = 'resetSynchronizer' pllOut ('unsafeToAsyncReset' pllStable)+  in  'withClockReset' pllOut rstSync f+@++-}++#ifdef CLASH_MULTIPLE_HIDDEN+type HiddenClockName dom = AppendSymbol dom "_clk"+type HiddenResetName dom = AppendSymbol dom "_rst"+type HiddenEnableName dom = AppendSymbol dom "_en"+#else+type HiddenClockName (dom :: Domain) = "clock"+type HiddenResetName (dom :: Domain) = "reset"+type HiddenEnableName (dom :: Domain) = "enable"+#endif++-- | A /constraint/ that indicates the component has a hidden 'Clock'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenClock dom =+  ( Hidden (HiddenClockName dom) (Clock dom)+  , KnownDomain dom )++-- | A /constraint/ that indicates the component needs a 'Reset'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenReset dom =+  ( Hidden (HiddenResetName dom) (Reset dom)+  , KnownDomain dom )++-- | A /constraint/ that indicates the component needs a 'Enable'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenEnable dom =+  ( Hidden (HiddenEnableName dom) (Enable dom)+  , KnownDomain dom )++-- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',+-- and an 'Enable' belonging to the same dom.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenClockResetEnable dom  =+  ( HiddenClock dom+  , HiddenReset dom+  , HiddenEnable dom+  )++-- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',+-- and an 'Enable' belonging to the 'System' dom.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type SystemClockResetEnable =+  ( Hidden (HiddenClockName System) (Clock System)+  , Hidden (HiddenResetName System) (Reset System)+  , Hidden (HiddenEnableName System) (Enable System)+  )++-- | Expose a hidden 'Clock' argument of a component, so it can be applied+-- explicitly.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single+-- domain. For example, this function will refuse when:+--+-- @+-- r ~ HiddenClock dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenClock dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to expose a clock of a component working on multiple domains+-- (such as the first example), use 'exposeSpecificClock'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a /polymorphic/ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeClock reg clockGen+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force exposeClock to work on System (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeClock @System reg clockGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+exposeClock+  :: forall dom  r+   .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     (HiddenClock dom => r)+  -- ^ The component with a hidden clock+  -> (KnownDomain dom => Clock dom -> r)+  -- ^ The component with its clock argument exposed+exposeClock = \f clk -> exposeSpecificClock (const f) clk (Proxy @dom)+{-# INLINE exposeClock #-}++-- | Expose a hidden 'Clock' argument of a component, so it can be applied+-- explicitly. This function can be used on components with multiple domains.+-- As opposed to 'exposeClock', callers should explicitly state what the clock+-- domain is. See the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'exposeSpecificClock' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = exposeSpecificClock @System reg clockGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = exposeSpecificClock @@dom reg 'clockGen'+-- @+--+exposeSpecificClock+   :: forall dom  r+   . WithSpecificDomain dom r+  => (HiddenClock dom => r)+  -- ^ The component with a hidden clock+  -> (KnownDomain dom => Clock dom -> r)+  -- ^ The component with its clock argument exposed+exposeSpecificClock = \f clk -> expose @(HiddenClockName dom) f clk+{-# INLINE exposeSpecificClock #-}++-- | Hide the 'Clock' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideClock+  :: forall dom r+   . HiddenClock dom+  => (Clock dom -> r)+  -- ^ Function whose clock argument you want to hide+  -> r+hideClock = \f -> f (fromLabel @(HiddenClockName dom))+{-# INLINE hideClock #-}++-- | Connect an explicit 'Clock' to a function with a hidden 'Clock'.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenClock dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenClock dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to connect a clock to a component working on multiple domains+-- (such as the first example), use 'withSpecificClock'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a _polymorphic_ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withClock clockGen reg+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force withClock to work on signal (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withClock @System clockGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+withClock+  :: forall dom r+   .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     KnownDomain dom+  => Clock dom+  -- ^ The 'Clock' we want to connect+  -> (HiddenClock dom => r)+  -- ^ The function with a hidden 'Clock' argument+  -> r+withClock clk f = withSpecificClock clk (const f) (Proxy @dom)+{-# INLINE withClock #-}++-- | Connect an explicit 'Clock' to a function with a hidden 'Clock'. This+-- function can be used on components with multiple domains. As opposed to+-- 'exposeClock', callers should explicitly state what the clock domain is. See+-- the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'withSpecificClock' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = withClock @System clockGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = withClock @@dom 'clockGen' reg+-- @+--+withSpecificClock+  :: forall dom r+   . (KnownDomain dom, WithSpecificDomain dom r)+  => Clock dom+  -- ^ The 'Clock' we want to connect+  -> (HiddenClock dom => r)+  -- ^ The function with a hidden 'Clock' argument+  -> r+withSpecificClock = \clk f -> expose @(HiddenClockName dom) f clk+{-# INLINE withSpecificClock #-}++-- | Connect a hidden 'Clock' to an argument where a normal 'Clock' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasClock+  :: forall dom+   . HiddenClock dom+  => Clock dom+hasClock = fromLabel @(HiddenClockName dom)+{-# INLINE hasClock #-}++-- | Expose a hidden 'Reset' argument of a component, so it can be applied+-- explicitly.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenReset dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenReset dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to expose a reset of a component working on multiple domains+-- (such as the first example), use 'exposeSpecificReset'.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+#endif+-- === __Example__+-- Usage with a /polymorphic/ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeReset reg resetGen+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force exposeReset to work on System (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeReset @System reg resetGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+exposeReset+  :: forall dom r+   .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     (HiddenReset dom => r)+  -- ^ The component with a hidden reset+  -> (KnownDomain dom => Reset dom -> r)+  -- ^ The component with its reset argument exposed+exposeReset = \f rst -> exposeSpecificReset (const f) rst (Proxy @dom)+{-# INLINE exposeReset #-}++-- | Expose a hidden 'Reset' argument of a component, so it can be applied+-- explicitly. This function can be used on components with multiple domains.+-- As opposed to 'exposeReset', callers should explicitly state what the reset+-- domain is. See the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'exposeSpecificReset' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = exposeSpecificReset @System reg resetGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = exposeSpecificReset @@dom reg 'resetGen'+-- @+--+exposeSpecificReset+  :: forall dom r+   . WithSpecificDomain dom r+  => (HiddenReset dom => r)+  -- ^ The component with a hidden reset+  -> (KnownDomain dom => Reset dom -> r)+  -- ^ The component with its reset argument exposed+exposeSpecificReset = \f rst -> expose @(HiddenResetName dom) f rst+{-# INLINE exposeSpecificReset #-}++-- | Hide the 'Reset' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideReset+  :: forall dom r+   . HiddenReset dom+  => (Reset dom -> r)+  -- ^ Component whose reset argument you want to hide+  -> r+hideReset = \f -> f (fromLabel @(HiddenResetName dom))+{-# INLINE hideReset #-}++-- | Connect an explicit 'Reset' to a function with a hidden 'Reset'.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenReset dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenReset dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to connect a reset to a component working on multiple domains+-- (such as the first example), use 'withSpecificReset'.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+#endif+-- === __Example__+-- Usage with a _polymorphic_ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withReset resetGen reg+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force withReset to work on signal (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withReset @System resetGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+withReset+  :: forall dom r+   .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     KnownDomain dom+  => Reset dom+  -- ^ The 'Reset' we want to connect+  -> (HiddenReset dom => r)+  -- ^ The function with a hidden 'Reset' argument+  -> r+withReset = \rst f -> expose @(HiddenResetName dom) f rst+{-# INLINE withReset #-}++-- | Connect an explicit 'Reset' to a function with a hidden 'Reset'. This+-- function can be used on components with multiple domains. As opposed to+-- 'exposeReset', callers should explicitly state what the reset domain is. See+-- the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'withSpecificReset' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = withReset @System resetGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = withReset @@dom 'resetGen' reg+-- @+--+withSpecificReset+  :: forall dom r+   . (KnownDomain dom, WithSpecificDomain dom r)+  => Reset dom+  -- ^ The 'Reset' we want to connect+  -> (HiddenReset dom => r)+  -- ^ The function with a hidden 'Reset' argument+  -> r+withSpecificReset = \rst f -> expose @(HiddenResetName dom) f rst+{-# INLINE withSpecificReset #-}++-- | Connect a hidden 'Reset' to an argument where a normal 'Reset' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasReset+  :: forall dom+   . HiddenReset dom+  => Reset dom+hasReset = fromLabel @(HiddenResetName dom)+{-# INLINE hasReset #-}++-- | Expose a hidden 'Enable' argument of a component, so it can be applied+-- explicitly.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenEnable dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenEnable dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to expose a enable of a component working on multiple domains+-- (such as the first example), use 'exposeSpecificEnable'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a /polymorphic/ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeEnable reg enableGen+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force exposeEnable to work on System (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeEnable @System reg enableGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+exposeEnable+  :: forall dom  r .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     (HiddenEnable dom => r)+  -- ^ The component with a hidden reset+  -> (KnownDomain dom => Enable dom -> r)+  -- ^ The component with its reset argument exposed+exposeEnable = \f gen -> exposeSpecificEnable (const f) gen (Proxy @dom)+{-# INLINE exposeEnable #-}++-- | Expose a hidden 'Enable' argument of a component, so it can be applied+-- explicitly. This function can be used on components with multiple domains.+-- As opposed to 'exposeEnable', callers should explicitly state what the enable+-- domain is. See the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'exposeSpecificEnable' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = exposeSpecificEnable @System reg enableGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = exposeSpecificEnable @@dom reg 'enableGen'+-- @+--+exposeSpecificEnable+  :: forall dom r+   . WithSpecificDomain dom r+  => (HiddenEnable dom => r)+  -- ^ The component with a hidden reset+  -> (KnownDomain dom => Enable dom -> r)+  -- ^ The component with its reset argument exposed+exposeSpecificEnable = \f gen -> expose @(HiddenEnableName dom) f gen+{-# INLINE exposeSpecificEnable #-}++-- | Hide the 'Enable' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideEnable+  :: forall dom r+   . HiddenEnable dom+  => (Enable dom -> r)+  -- ^ Component whose reset argument you want to hide+  -> r+hideEnable = \f -> f (fromLabel @(HiddenEnableName dom))+{-# INLINE hideEnable #-}++-- | Connect an explicit 'Enable' to a function with a hidden 'Enable'.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenEnable dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenEnable dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to connect a enable to a component working on multiple domains+-- (such as the first example), use 'withSpecificEnable'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a _polymorphic_ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withEnable enableGen reg+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force withEnable to work on signal (hence 'sampleN' not needing an explicit+-- domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withEnable @System enableGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+withEnable+  :: forall dom r+   . KnownDomain dom+#ifdef CLASH_MULTIPLE_HIDDEN+  => WithSingleDomain dom r+#endif+  => Enable dom+  -- ^ The 'Enable' we want to connect+  -> (HiddenEnable dom => r)+  -- ^ The function with a hidden 'Enable' argument+  -> r+withEnable = \gen f -> expose @(HiddenEnableName dom) f gen+{-# INLINE withEnable #-}++-- | Connect an explicit 'Reset' to a function with a hidden 'Enable'. This+-- function can be used on components with multiple domains. As opposed to+-- 'exposeEnable', callers should explicitly state what the enable domain is. See+-- the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'withSpecificEnable' can only be used when it can find the specified domain+-- in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = withEnable @System enableGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = withEnable @@dom 'enableGen' reg+-- @+--+withSpecificEnable+  :: forall dom r+   . (KnownDomain dom, WithSpecificDomain dom r)+  => Enable dom+  -- ^ The 'Enable' we want to connect+  -> (HiddenEnable dom => r)+  -- ^ The function with a hidden 'Enable' argument+  -> r+withSpecificEnable = \gen f -> expose @(HiddenEnableName dom) f gen+{-# INLINE withSpecificEnable #-}++-- | Connect a hidden 'Enable' to an argument where a normal 'Enable' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasEnable+  :: forall dom+   . HiddenEnable dom+  => Enable dom+hasEnable = fromLabel @(HiddenEnableName dom)+{-# INLINE hasEnable #-}+++-- | Expose a hidden 'Clock', 'Reset', and 'Enable' argument of a component, so+-- it can be applied explicitly.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenClockResetEnable dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to expose a clock, reset, and enable of a component working on+-- multiple domains (such as the first example), use 'exposeSpecificClockResetEnable'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a /polymorphic/ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeClockResetEnable reg clockGen resetGen enableGen+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force exposeClockResetEnable to work on System (hence 'sampleN' not needing an+-- explicit domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = exposeClockResetEnable @System reg clockGen resetGen enableGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Usage in a testbench context:+--+-- @+-- topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)+-- topEntity = concat+--+-- testBench :: Signal System Bool+-- testBench = done+--   where+--     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)+--     expectedOutput = outputVerifier' ((1:>2:>3:>4:>5:>6:>Nil):>Nil)+--     done           = exposeClockResetEnable (expectedOutput (topEntity <$> testInput)) clk rst+--     clk            = tbSystemClockGen (not <\$\> done)+--     rst            = systemResetGen+-- @+exposeClockResetEnable+  :: forall dom r .+#ifdef CLASH_MULTIPLE_HIDDEN+     WithSingleDomain dom r =>+#endif+     (HiddenClockResetEnable dom => r)+  -- ^ The component with hidden clock, reset, and enable arguments+  -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+  -- ^ The component with its clock, reset, and enable arguments exposed+exposeClockResetEnable =+  \f clk rst en ->+    exposeSpecificClock (exposeSpecificReset (exposeEnable f)) clk rst en+{-# INLINE exposeClockResetEnable #-}++#ifdef CLASH_MULTIPLE_HIDDEN+-- | Expose a hidden 'Clock', 'Reset', and 'Enable' argument of a component, so+-- it can be applied explicitly. This function can be used on components with+-- multiple domains. As opposed to 'exposeClockResetEnable', callers should+-- explicitly state what the enable domain is. See the examples for more+-- information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'exposeSpecificClockResetEnable' can only be used when it can find the+-- specified domain in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = exposeSpecificClockResetEnable @System reg clockGen resetGen enableGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = exposeSpecificClockResetEnable @@dom reg 'clockGen' 'resetGen' 'enableGen'+-- @+--+exposeSpecificClockResetEnable+  :: forall dom r+   . WithSpecificDomain dom r+  => (HiddenClockResetEnable dom => r)+  -- ^ The component with hidden clock, reset, and enable arguments+  -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+  -- ^ The component with its clock, reset, and enable arguments exposed+exposeSpecificClockResetEnable =+  \f clk rst en ->+    exposeSpecificClock (exposeSpecificReset (exposeSpecificEnable f)) clk rst en+{-# INLINE exposeSpecificClockResetEnable #-}+#endif++-- -- | Hide the 'Clock' and 'Reset' arguments of a component, so they can be+-- -- routed implicitly+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideClockResetEnable+  :: forall dom r+   . HiddenClockResetEnable dom+  => (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+  -- ^ Component whose clock, reset, and enable argument you want to hide+  -> r+hideClockResetEnable =+  \f ->+    f+      (fromLabel @(HiddenClockName dom))+      (fromLabel @(HiddenResetName dom))+      (fromLabel @(HiddenEnableName dom))+{-# INLINE hideClockResetEnable #-}++-- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with a+-- hidden 'Clock', 'Reset', and 'Enable'.+--+#ifdef CLASH_MULTIPLE_HIDDEN+-- This function can only be used on components with a single domain. For+-- example, this function will refuse when:+--+-- @+-- r ~ HiddenClockResetEnable dom => Signal dom1 a -> Signal dom2 a+-- @+--+-- But will work when:+--+-- @+-- r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a+-- @+--+-- If you want to connect a enable to a component working on multiple domains+-- (such as the first example), use 'withSpecificClockResetEnable'.+--+#endif+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- Usage with a _polymorphic_ domain:+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withClockResetEnable clockGen resetGen enableGen reg+-- >>> sampleN @System 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Force withClockResetEnable to work on signal (hence 'sampleN' not needing+-- an explicit domain later):+--+-- >>> reg = register 5 (reg + 1)+-- >>> sig = withClockResetEnable @System clockGen resetGen enableGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+withClockResetEnable+  :: forall dom r+   . KnownDomain dom+#ifdef CLASH_MULTIPLE_HIDDEN+  => WithSingleDomain dom r+#endif+  => Clock dom+  -- ^ The 'Clock' we want to connect+  -> Reset dom+  -- ^ The 'Reset' we want to connect+  -> Enable dom+  -- ^ The 'Enable' we want to connect+  -> (HiddenClockResetEnable dom => r)+  -- ^ The function with a hidden 'Clock', hidden 'Reset', and hidden+  -- 'Enable' argument+  -> r+withClockResetEnable =+  \clk rst en f -> withSpecificClockResetEnable clk rst en (const f) (Proxy @dom)+{-# INLINE withClockResetEnable #-}++-- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with a+-- hidden 'Clock', 'Reset', and 'Enable'. This function can be used on components+-- with multiple domains. As opposed to 'exposeClockResetEnable', callers should+-- explicitly state what the enable domain is. See the examples for more+-- information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'withSpecificClockResetEnable' can only be used when it can find the+-- specified domain in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = withClockResetEnable @System clockGen resetGen enableGen reg+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = withClockResetEnable @@dom 'clockGen' 'resetGen' 'enableGen' reg+-- @+--+withSpecificClockResetEnable+  :: forall dom r+   . (KnownDomain dom, WithSpecificDomain dom r)+  => Clock dom+  -- ^ The 'Clock' we want to connect+  -> Reset dom+  -- ^ The 'Reset' we want to connect+  -> Enable dom+  -- ^ The 'Enable' we want to connect+  -> (HiddenClockResetEnable dom => r)+  -- ^ The function with a hidden 'Clock', hidden 'Reset', and hidden+  -- 'Enable' argument+  -> r+withSpecificClockResetEnable =+  \clk rst en f -> withSpecificClock clk (withSpecificReset rst (withSpecificEnable en f))+{-# INLINE withSpecificClockResetEnable #-}++-- * Basic circuit functions++-- | Special version of 'delay' that doesn't take enable signals of any kind.+-- Initial value will be undefined.+dflipflop+  :: forall dom a+   . ( HiddenClock dom+     , NFDataX a )+  => Signal dom a+  -> Signal dom a+dflipflop =+  E.dflipflop (fromLabel @(HiddenClockName dom))+{-# INLINE dflipflop #-}++-- | 'delay' @s@ delays the values in 'Signal' @s@ for once cycle, the value+-- at time 0 is /dflt/.+--+-- >>> sampleN @System 3 (delay 0 (fromList [1,2,3,4]))+-- [0,1,2]+delay+  :: forall dom a+   . ( NFDataX a+     , HiddenClock dom+     , HiddenEnable dom  )+  => a+  -- ^ Initial value+  -> Signal dom a+  -- ^ Signal to delay+  -> Signal dom a+delay dflt i =+  delay#+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenEnableName dom))+    dflt+    i+{-# INLINE delay #-}++-- | Version of 'delay' that only updates when its second argument is a 'Just'+-- value.+--+-- >>> let input = fromList [Just 1, Just 2, Nothing, Nothing, Just 5, Just 6, Just (7::Int)]+-- >>> sampleN @System 7 (delayMaybe 0 input)+-- [0,1,2,2,2,5,6]+delayMaybe+  :: forall dom a+   . ( NFDataX a+     , HiddenClock dom+     , HiddenEnable dom  )+  => a+  -- ^ Initial value+  -> Signal dom (Maybe a)+  -> Signal dom a+delayMaybe dflt i =+  E.delayMaybe+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenEnableName dom))+    dflt+    i+{-# INLINE delayMaybe #-}++-- | Version of 'delay' that only updates when its second argument is asserted.+--+-- >>> let input = fromList [1,2,3,4,5,6,7::Int]+-- >>> let enable = fromList [True,True,False,False,True,True,True]+-- >>> sampleN @System 7 (delayEn 0 enable input)+-- [0,1,2,2,2,5,6]+delayEn+  :: forall dom a+   . ( NFDataX a+     , HiddenClock dom+     , HiddenEnable dom  )+  => a+  -- ^ Initial value+  -> Signal dom Bool+  -- ^ Enable+  -> Signal dom a+  -> Signal dom a+delayEn dflt en i =+  E.delayEn+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenEnableName dom))+    dflt+    en+    i+{-# INLINE delayEn #-}++-- | 'register' @i s@ delays the values in 'Signal' @s@ for one cycle, and sets+-- the value at time 0 to @i@+--+-- >>> sampleN @System 5 (register 8 (fromList [1,1,2,3,4]))+-- [8,8,1,2,3]+register+  :: forall dom a+   . ( HiddenClockResetEnable dom+     , NFDataX a )+  => a+  -- ^ Reset value+  --+  -- 'register' outputs the reset value when the reset value is active+  -> Signal dom a+  -> Signal dom a+register i s =+  E.register+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenResetName dom))+    (fromLabel @(HiddenEnableName dom))+    i+    s+{-# INLINE register #-}+infixr 3 `register`++-- | Version of 'register' that only updates its content when its second+-- argument is a 'Just' value. So given:+--+-- @+-- sometimes1 = s where+--   s = 'register' Nothing (switch '<$>' s)+--+--   switch Nothing = Just 1+--   switch _       = Nothing+--+-- countSometimes = s where+--   s     = 'regMaybe' 0 (plusM ('pure' '<$>' s) sometimes1)+--   plusM = 'liftA2' (liftA2 (+))+-- @+--+-- We get:+--+-- >>> sampleN @System 9 sometimes1+-- [Nothing,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]+-- >>> sampleN @System 9 countSometimes+-- [0,0,0,1,1,2,2,3,3]+regMaybe+  :: forall dom a+   . ( HiddenClockResetEnable dom+     , NFDataX a )+  => a+  -- ^ Reset value. 'regMaybe' outputs the reset value when the reset is active.+  -> Signal dom (Maybe a)+  -> Signal dom a+regMaybe initial iM =+  E.regMaybe+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenResetName dom))+    (fromLabel @(HiddenEnableName dom))+    initial+    iM+{-# INLINE regMaybe #-}+infixr 3 `regMaybe`++-- | Version of 'register' that only updates its content when its second argument+-- is asserted. So given:+--+-- @+-- oscillate = 'register' False ('not' '<$>' oscillate)+-- count     = 'regEn' 0 oscillate (count + 1)+-- @+--+-- We get:+--+-- >>> sampleN @System 9 oscillate+-- [False,False,True,False,True,False,True,False,True]+-- >>> sampleN @System 9 count+-- [0,0,0,1,1,2,2,3,3]+regEn+  :: forall dom a+   . ( HiddenClockResetEnable dom+     , NFDataX a )+  => a+  -- ^ Reset value+  --+  -- 'regEn' outputs the reset value when the reset value is active+  -> Signal dom Bool+  -> Signal dom a+  -> Signal dom a+regEn initial en i =+  E.regEn+    (fromLabel @(HiddenClockName dom))+    (fromLabel @(HiddenResetName dom))+    (fromLabel @(HiddenEnableName dom))+    initial+    en+    i+{-# INLINE regEn #-}++-- * Signal -> List conversion++-- | Get an infinite list of samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sample' will supply them. The reset will be asserted for a single+-- cycle. 'sample' will not drop the value produced by the circuit while+-- the reset was asserted. If you want this, or if you want more than a+-- single cycle reset, consider using 'sampleWithReset'.+--+-- __NB__: This function is not synthesizable+sample+  :: forall dom a+   . ( KnownDomain dom+     , NFDataX a )+  => (HiddenClockResetEnable dom  => Signal dom a)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sample s =+  S.sample (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sample #-}++-- | Get a list of /n/ samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sampleN @System 3 s == [s0, s1, s2]+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sampleN' will supply them. The reset will be asserted for a single+-- cycle. 'sampleN' will not drop the value produced by the circuit while+-- the reset was asserted. If you want this, or if you want more than a+-- single cycle reset, consider using 'sampleWithResetN'.+--+-- __NB__: This function is not synthesizable+sampleN+  :: forall dom a+   . ( KnownDomain dom+     , NFDataX a )+  => Int+  -- ^ Number of samples to produce+  -> (HiddenClockResetEnable dom => Signal dom a)+  -- ^ 'Signal' to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sampleN n s0 =+  let s1 = exposeClockResetEnable @dom s0 clockGen resetGen enableGen in+  S.sampleN n s1+{-# NOINLINE sampleN #-}++-- | Get a list of samples from a 'Signal', while asserting the reset line+-- for /n/ clock cycles. 'sampleWithReset' does not return the first /n/ cycles,+-- i.e., when the reset is asserted.+--+-- __NB__: This function is not synthesizable+sampleWithReset+  :: forall dom a m+   . ( KnownDomain dom+     , NFDataX a+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> (HiddenClockResetEnable dom => Signal dom a)+  -- ^ 'Signal' to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sampleWithReset nReset f0 =+  let f1 = exposeClockResetEnable f0 clockGen (resetGenN @dom nReset) enableGen in+  drop (snatToNum nReset) (S.sample f1)+{-# NOINLINE sampleWithReset #-}++-- | Get a fine list of /m/ samples from a 'Signal', while asserting the reset line+-- for /n/ clock cycles. 'sampleWithReset' does not return the first /n/ cycles,+-- i.e., while the reset is asserted.+--+-- __NB__: This function is not synthesizable+sampleWithResetN+  :: forall dom a m+   . ( KnownDomain dom+     , NFDataX a+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> Int+  -- ^ Number of samples to produce+  -> (HiddenClockResetEnable dom => Signal dom a)+  -- ^ 'Signal' to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sampleWithResetN nReset nSamples f =+  take nSamples (sampleWithReset nReset f)++-- | /Lazily/ get an infinite list of samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sample_lazy' will supply them. The reset will be asserted for a+-- single cycle. 'sample_lazy' will not drop the value produced by the+-- circuit while the reset was asserted.+--+-- __NB__: This function is not synthesizable+sample_lazy+  :: forall dom a+   . KnownDomain dom+  => (HiddenClockResetEnable dom  => Signal dom a)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sample_lazy s =+  S.sample_lazy (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sample_lazy #-}++-- | Lazily get a list of /n/ samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sampleN @System 3 s == [s0, s1, s2]+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sampleN_lazy' will supply them. The reset will be asserted for a+-- single cycle. 'sampleN_lazy' will not drop the value produced by the+-- circuit while the reset was asserted.+--+-- __NB__: This function is not synthesizable+sampleN_lazy+  :: forall dom a+   . KnownDomain dom+  => Int+  -> (HiddenClockResetEnable dom  => Signal dom a)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+sampleN_lazy n s =+  S.sampleN_lazy n (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sampleN_lazy #-}++-- * Simulation functions++-- | Simulate a (@'Signal' a -> 'Signal' b@) function given a list of samples+-- of type /a/+--+-- >>> simulate @System (register 8) [1, 2, 3]+-- [8,1,2,3...+-- ...+--+-- Where 'System' denotes the /domain/ to simulate on. The reset line is+-- asserted for a single cycle. The first value is therefore supplied twice to+-- the circuit: once while reset is high, and once directly after. The first+-- /output/ value (the value produced while the reset is asserted) is dropped.+--+-- If you only want to simulate a finite number of samples, see 'simulateN'. If+-- you need the reset line to be asserted for more than one cycle or if you+-- need a custom reset value, see 'simulateWithReset' and 'simulateWithResetN'.+--+-- __NB__: This function is not synthesizable+simulate+  :: forall dom a b+   . ( KnownDomain dom+     , NFDataX a+     , NFDataX b )+  => (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+  -- ^ Circuit to simulate, whose source potentially has a hidden clock, reset,+  -- and/or enable.+  -> [a]+  -> [b]+simulate f as = simulateWithReset (SNat @1) (head as) f as+{-# INLINE simulate #-}++-- | Same as 'simulate', but only sample the first /Int/ output values.+--+-- __NB__: This function is not synthesizable+simulateN+  :: forall dom a b+   . ( KnownDomain dom+     , NFDataX a+     , NFDataX b )+  => Int+  -- ^ Number of cycles to simulate (excluding cycle spent in reset)+  -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+  -> [b]+simulateN n f as = simulateWithResetN (SNat @1) (head as) n f as+{-# INLINE simulateN #-}++-- | Same as 'simulate', but with the reset line asserted for /n/ cycles. Similar+-- to 'simulate', 'simulateWithReset' will drop the output values produced while+-- the reset is asserted. While the reset is asserted, the reset value /a/ is+-- supplied to the circuit.+simulateWithReset+  :: forall dom a b m+   . ( KnownDomain dom+     , NFDataX a+     , NFDataX b+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> a+  -- ^ Reset value+  -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+  -> [b]+simulateWithReset n resetVal f as =+  S.simulateWithReset n resetVal (exposeClockResetEnable f) as+{-# INLINE simulateWithReset #-}++-- | Same as 'simulateWithReset', but only sample the first /Int/ output values.+simulateWithResetN+  :: forall dom a b m+   . ( KnownDomain dom+     , NFDataX a+     , NFDataX b+     , 1 <= m )+  => SNat m+  -- ^ Number of cycles to assert the reset+  -> a+  -- ^ Reset value+  -> Int+  -- ^ Number of cycles to simulate (excluding cycles spent in reset)+  -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+  -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+  -- (and reset)+  -> [a]+  -> [b]+simulateWithResetN nReset resetVal nSamples f as =+  S.simulateWithResetN nReset resetVal nSamples (exposeClockResetEnable f) as+{-# INLINE simulateWithResetN #-}+++-- | /Lazily/ simulate a (@'Signal' a -> 'Signal' b@) function given a list of+-- samples of type /a/+--+-- >>> simulate @System (register 8) [1, 2, 3]+-- [8,1,2,3...+-- ...+--+-- __NB__: This function is not synthesizable+simulate_lazy+  :: forall dom a b+   . KnownDomain dom+  => (HiddenClockResetEnable dom  =>+      Signal dom a -> Signal dom b)+  -- ^ Function we want to simulate, whose components potentially have a hidden+  -- clock (and reset)+  -> [a]+  -> [b]+simulate_lazy f0 =+  let f1 = exposeClockResetEnable @dom f0 clockGen resetGen enableGen in+  tail . S.simulate_lazy f1 . dup1+{-# NOINLINE simulate_lazy #-}++-- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of+-- samples of type @a@+--+-- >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(1,1),(2,2),(3,3)...+-- ...+--+-- __NB__: This function is not synthesizable+simulateB+  :: forall dom a b+   . ( KnownDomain dom+     , Bundle a+     , Bundle b+     , NFDataX a+     , NFDataX b+     )+  => (HiddenClockResetEnable dom  =>+      Unbundled dom a -> Unbundled dom b)+  -- ^ Function we want to simulate, whose components potentially have a hidden+  -- clock (and reset)+  -> [a]+  -> [b]+simulateB f0 =+  tail . S.simulateB f1 . dup1+ where+  f1 =+    withSpecificClockResetEnable+      @dom+      clockGen+      resetGen+      enableGen+      (const f0)+      (Proxy @dom)+{-# NOINLINE simulateB #-}++-- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a+-- list of samples of type @a@+--+-- >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(1,1),(2,2),(3,3)...+-- ...+--+-- __NB__: This function is not synthesizable+simulateB_lazy+  :: forall dom a b+   . ( KnownDomain dom+     , Bundle a+     , Bundle b )+  => (HiddenClockResetEnable dom  =>+      Unbundled dom a -> Unbundled dom b)+  -- ^ Function we want to simulate, whose components potentially have a hidden+  -- clock (and reset)+  -> [a]+  -> [b]+simulateB_lazy f0 =+  tail . S.simulateB_lazy f1 . dup1+ where+  f1 =+    withSpecificClockResetEnable+      @dom+      clockGen+      resetGen+      enableGen+      (const f0)+      (Proxy @dom)+{-# NOINLINE simulateB_lazy #-}++dup1 :: [a] -> [a]+dup1 (x:xs) = x:x:xs+dup1 _      = error "empty list"++-- * QuickCheck combinators++-- |  @testFor n s@ tests the signal /s/ for /n/ cycles.+--+-- __NB__: This function is not synthesizable+testFor+  :: KnownDomain dom+  => Int+  -- ^ The number of cycles we want to test for+  -> (HiddenClockResetEnable dom  => Signal dom Bool)+  -- ^ 'Signal' we want to evaluate, whose source potentially has a hidden clock+  -- (and reset)+  -> Property+testFor n s = property (and (Clash.Signal.sampleN n s))++#ifdef CLASH_MULTIPLE_HIDDEN+-- ** Synchronization primitive+-- | Implicit version of 'Clash.Explicit.Signal.unsafeSynchronizer'.+unsafeSynchronizer+  :: forall dom1 dom2 a+   . ( HiddenClock dom1+     , HiddenClock dom2 )+  => Signal dom1 a+  -> Signal dom2 a+unsafeSynchronizer =+  hideClock (hideClock S.unsafeSynchronizer)+#endif++-- | Hold reset for a number of cycles relative to an implicit reset signal.+--+-- Example:+--+-- >>> sampleN @System 8 (unsafeToHighPolarity (holdReset (SNat @2)))+-- [True,True,True,False,False,False,False,False]+--+-- 'holdReset' holds the reset for an additional 2 clock cycles for a total+-- of 3 clock cycles where the reset is asserted.+--+holdReset+  :: forall dom m+   . HiddenClockResetEnable dom+  => SNat m+  -- ^ Hold for /m/ cycles, counting from the moment the incoming reset+  -- signal becomes deasserted.+  -> Reset dom+holdReset m =+  hideClockResetEnable (\clk rst en -> E.holdReset clk en m rst)++-- | Like 'fromList', but resets on reset and has a defined reset value.+--+-- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])+-- >>> let res = withReset rst (fromListWithReset Nothing [Just 'a', Just 'b', Just 'c'])+-- >>> sampleN @System 6 res+-- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']+--+-- __NB__: This function is not synthesizable+fromListWithReset+  :: forall dom a+   . (HiddenReset dom, NFDataX a)+  => a+  -> [a]+  -> Signal dom a+fromListWithReset = hideReset E.fromListWithReset+{-# INLINE fromListWithReset #-}++#ifdef CLASH_MULTIPLE_HIDDEN+-- | Convert between different types of reset, adding a synchronizer in case+-- it needs to convert from an asynchronous to a synchronous reset.+convertReset+  :: forall domA domB+   . ( HiddenClock domA+     , HiddenClock domB+     )+  => Reset domA+  -> Reset domB+convertReset =+  E.convertReset hasClock hasClock+#endif
+ src/Clash/Signal/BiSignal.hs view
@@ -0,0 +1,282 @@+{-|+Copyright  :  (C) 2017, Google Inc.+                  2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++Wires are fundamentally bidirectional, and in traditional HDLs we can exploit+this aspect by explicitly marking the endpoint, or port, of such a wire as+/inout/, thereby making this port function as both a source and a drain for the+signals flowing over the wire.++Clash has support for 'inout' ports through the implementation of /BiSignal/s.+To cleanly map to functions (and thus support software simulation using Haskell),+a /BiSignal/ comes in two parts; the __in__ part:++@+'BiSignalIn' (ds :: 'BiSignalDefault') (dom :: 'Domain') (n :: Nat)+@++and the __out__ part:++@+'BiSignalOut' (ds :: 'BiSignalDefault') (dom :: 'Domain') (n :: Nat)+@++Where:++  * The internal representation is a 'BitVector'+  * /n/ indicates the number of bits in the 'BitVector'+  * /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements+    manipulating these BiSignals belong.+  * Lastly, /ds/ indicates the default behavior for the BiSignal if nothing is+    being written (pull-down, pull-up, or undefined).++'BiSignalIn' is used by Clash to generate the 'inout' ports on a HDL level,+while 'BiSignalOut' is only used for simulation purposes and generally discarded+by the compiler.++= Example++The following describes a system where two circuits, in alternating fashion,+read the current value from the /bus/, increment it, and write it on the next+cycle.++@+-- | Alternatively read / increment+write+counter+  :: (Bool, Int)+  -- ^ Internal flip + previous read+  -> Int+  -- ^ Int from inout+  -> ((Bool, Int), Maybe Int)+counter (write, prevread) i = ((write', prevread'), output)+  where+    output    = if write then Just (succ prevread) else Nothing+    prevread' = if write then prevread else i+    write' = not write++-- | Write on odd cyles+f :: Clock System+  -> Reset System+  -> BiSignalIn  Floating System (BitSize Int)+  -> BiSignalOut Floating System (BitSize Int)+f clk rst s = writeToBiSignal s (mealy clk rst counter (False, 0) (readFromBiSignal s))++-- | Write on even cyles+g :: Clock System+  -> Reset System+  -> BiSignalIn  Floating System (BitSize Int)+  -> BiSignalOut Floating System (BitSize Int)+g clk rst s = writeToBiSignal s (mealy clk rst counter (True, 0) (readFromBiSignal s))+++-- | Connect the /f/ and /g/ circuits to the same bus+topEntity+  :: Clock System+  -> Reset System+  -> Signal System Int+topEntity clk rst = readFromBiSignal bus'+  where+    bus  = mergeBiSignalOuts $ f clk rst bus' :> g clk rst bus' :> Nil+    bus' = veryUnsafeToBiSignalIn bus+@+-}++{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE InstanceSigs           #-}+{-# LANGUAGE KindSignatures         #-}+{-# LANGUAGE MagicHash              #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE RankNTypes             #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeOperators          #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}++module Clash.Signal.BiSignal (+    BiSignalIn()+  , BiSignalOut()+  , BiSignalDefault(..)+  , mergeBiSignalOuts+  , readFromBiSignal+  , writeToBiSignal+  , veryUnsafeToBiSignalIn+  ) where++import           Data.Kind                  (Type)+import           Data.List                  (intercalate)+import           Data.Maybe                 (fromMaybe,fromJust,isJust)++import           Clash.Class.BitPack        (BitPack (..))+import           Clash.Sized.BitVector      (BitVector)+import qualified Clash.Sized.Vector         as V+import           Clash.Sized.Vector         (Vec)+import           Clash.Signal.Internal      (Signal(..), Domain, head#, tail#)+import           Clash.XException           (errorX)++import           GHC.TypeLits               (KnownNat, Nat)+import           GHC.Stack                  (HasCallStack)+import           Data.Reflection            (Given (..))++-- | Used to specify the /default/ behavior of a 'BiSignal', i.e. what value is+-- read when no value is being written to it.+data BiSignalDefault+  = PullUp+  -- ^ __inout__ port behaves as if connected to a pull-up resistor+  | PullDown+  -- ^ __inout__ port behaves as if connected to a pull-down resistor+  | Floating+  -- ^ __inout__ port behaves as if is /floating/. Reading a /floating/+  -- 'BiSignal' value in simulation will yield an errorX (undefined value).+  deriving (Show)++-- | Singleton versions of 'BiSignalDefault'+data SBiSignalDefault :: BiSignalDefault -> Type where+  SPullUp   :: SBiSignalDefault 'PullUp+  SPullDown :: SBiSignalDefault 'PullDown+  SFloating :: SBiSignalDefault 'Floating++instance Given (SBiSignalDefault 'PullUp) where+  given = SPullUp++instance Given (SBiSignalDefault 'PullDown) where+  given = SPullDown++instance Given (SBiSignalDefault 'Floating) where+  given = SFloating++-- | The /in/ part of an __inout__ port+data BiSignalIn (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)+  = BiSignalIn (SBiSignalDefault ds) (Signal dom (Maybe (BitVector n)))++-- | The /out/ part of an __inout__ port+--+-- Wraps (multiple) writing signals. The semantics are such that only one of+-- the signals may write at a single time step.+newtype BiSignalOut (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)+  = BiSignalOut [Signal dom (Maybe (BitVector n))]++#if MIN_VERSION_base(4,11,0)+instance Semigroup (BiSignalOut defaultState dom n) where+  (BiSignalOut b1) <> (BiSignalOut b2) = BiSignalOut (b1 ++ b2)+#endif++-- | Monoid instance to support concatenating+--+-- __NB__ Not synthesizable+instance Monoid (BiSignalOut defaultState dom n) where+  mempty                                    = BiSignalOut []+#if !MIN_VERSION_base(4,11,0)+  mappend (BiSignalOut b1) (BiSignalOut b2) = BiSignalOut $ b1 ++ b2+#endif++-- /Lazily/ prepend a value to a 'BiSignalIn'.+--+-- Uses a /reified/ 'SBiSignalDefault', the 'Given' constraint, so we can fully+-- create 'BiSignalIn' "out of nowhere" when dealing with circular definitions.+prepend#+  :: Given (SBiSignalDefault ds)+  => Maybe (BitVector n)+  -> BiSignalIn ds d n+  -> BiSignalIn ds d n+prepend# a ~(BiSignalIn _ as) = BiSignalIn given (a :- as)++readFromBiSignal#+  :: ( HasCallStack+     , KnownNat n)+  => BiSignalIn ds d n+  -> Signal d (BitVector n)+readFromBiSignal# (BiSignalIn ds s) =+  case ds of+    SFloating -> fromMaybe (errorX " undefined value on BiSignalIn") <$> s+    SPullDown  -> fromMaybe minBound <$> s+    SPullUp    -> fromMaybe maxBound <$> s+{-# NOINLINE readFromBiSignal# #-}++-- | Read the value from an __inout__ port+readFromBiSignal+  :: ( HasCallStack+     , KnownNat (BitSize a)+     , BitPack a)+  => BiSignalIn ds d (BitSize a)+  -- ^ A 'BiSignalIn' with a number of bits needed to represent /a/+  -> Signal d a+readFromBiSignal = fmap unpack . readFromBiSignal#++-- | Combine several __inout__ signals into one.+mergeBiSignalOuts+  :: ( HasCallStack+     , KnownNat n+     )+  => Vec n (BiSignalOut defaultState dom m)+  -> BiSignalOut defaultState dom m+mergeBiSignalOuts = mconcat . V.toList+{-# NOINLINE mergeBiSignalOuts #-}++writeToBiSignal#+  :: HasCallStack+  => BiSignalIn ds d n+  -> Signal d (Maybe (BitVector n))+  -> Signal d Bool+  -> Signal d (BitVector n)+  -> BiSignalOut ds d n+-- writeToBiSignal# = writeToBiSignal#+writeToBiSignal# _ maybeSignal _ _ = BiSignalOut [maybeSignal]+{-# NOINLINE writeToBiSignal# #-}++-- | Write to an __inout__ port+writeToBiSignal+  :: (HasCallStack, BitPack a)+  => BiSignalIn ds d (BitSize a)+  -> Signal d (Maybe a)+  -- ^ Value to write+  --+  --   * /Just a/ writes an /a/ value+  --   * /Nothing/ puts the port in a /high-impedance/ state+  -> BiSignalOut ds d (BitSize a)+writeToBiSignal input writes =+  writeToBiSignal#+    input+    (fmap pack <$> writes)+    (isJust <$> writes)+    (pack . fromJust <$> writes)+{-# INLINE writeToBiSignal #-}++-- | Converts the 'out' part of a BiSignal to an 'in' part. In simulation it+-- checks whether multiple components are writing and will error accordingly.+-- Make sure this is only called ONCE for every BiSignal.+veryUnsafeToBiSignalIn+  :: ( HasCallStack+     , KnownNat n+     , Given (SBiSignalDefault ds)+     )+  => BiSignalOut ds d n+  -> BiSignalIn ds d n+veryUnsafeToBiSignalIn (BiSignalOut signals) = prepend# result biSignalOut'+  where+    -- Enforce that only one component is writing+    result = case filter (isJust . head#) signals of+      []  -> Nothing+      [w] -> head# w+      _   -> errorX err++    err = unwords+      [ "Multiple components wrote to the BiSignal. This is undefined behavior"+      , "in hardware and almost certainly a logic error. The components wrote:\n"+      , intercalate "\n  " (map (show . head#) signals)+      ]++    -- Recursive step+    biSignalOut' = veryUnsafeToBiSignalIn $ BiSignalOut $ map tail# signals+{-# NOINLINE veryUnsafeToBiSignalIn #-}
src/Clash/Signal/Bundle.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.+                  2017-2019, Myrtle Software Ltd, Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>  The Product/Signal isomorphism -} +{-# LANGUAGE CPP                    #-} {-# LANGUAGE DataKinds              #-} {-# LANGUAGE DefaultSignatures      #-} {-# LANGUAGE KindSignatures         #-}@@ -15,6 +16,9 @@ {-# LANGUAGE TypeFamilies           #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE TypeOperators          #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif  {-# LANGUAGE Trustworthy #-} @@ -25,13 +29,11 @@   ) where -import Control.Applicative          (liftA2) import GHC.TypeLits                 (KnownNat) import Prelude                      hiding (head, map, tail) -import Clash.NamedTypes             ((:::)) import Clash.Signal.Bundle.Internal (deriveBundleTuples)-import Clash.Signal.Internal        (Domain, Signal (..))+import Clash.Signal.Internal        (Signal (..), Domain) import Clash.Sized.BitVector        (Bit, BitVector) import Clash.Sized.Fixed            (Fixed) import Clash.Sized.Index            (Index)@@ -71,43 +73,44 @@ -- @ -- class Bundle a where-  type Unbundled (domain :: Domain) a = res | res -> domain a-  type Unbundled domain a = Signal domain a+  type Unbundled (dom :: Domain) a = res | res -> dom a+  type Unbundled dom a = Signal dom a   -- | Example:   --   -- @-  -- __bundle__ :: ('Signal' domain a, 'Signal' domain b) -> 'Signal' domain (a,b)+  -- __bundle__ :: ('Signal' dom a, 'Signal' dom b) -> 'Signal' dom (a,b)   -- @   --   -- However:   --   -- @-  -- __bundle__ :: 'Signal' domain 'Clash.Sized.BitVector.Bit' -> 'Signal' domain 'Clash.Sized.BitVector.Bit'+  -- __bundle__ :: 'Signal' dom 'Clash.Sized.BitVector.Bit' -> 'Signal' dom 'Clash.Sized.BitVector.Bit'   -- @-  bundle :: Unbundled domain a -> Signal domain a+  bundle :: Unbundled dom a -> Signal dom a    {-# INLINE bundle #-}-  default bundle :: (Signal domain a ~ Unbundled domain a)-                 => Unbundled domain a -> Signal domain a+  default bundle :: (Signal dom a ~ Unbundled dom a)+                 => Unbundled dom a -> Signal dom a   bundle s = s   -- | Example:   --   -- @-  -- __unbundle__ :: 'Signal' domain (a,b) -> ('Signal' domain a, 'Signal' domain b)+  -- __unbundle__ :: 'Signal' dom (a,b) -> ('Signal' dom a, 'Signal' dom b)   -- @   --   -- However:   --   -- @-  -- __unbundle__ :: 'Signal' domain 'Clash.Sized.BitVector.Bit' -> 'Signal' domain 'Clash.Sized.BitVector.Bit'+  -- __unbundle__ :: 'Signal' dom 'Clash.Sized.BitVector.Bit' -> 'Signal' dom 'Clash.Sized.BitVector.Bit'   -- @-  unbundle :: Signal domain a -> Unbundled domain a+  unbundle :: Signal dom a -> Unbundled dom a    {-# INLINE unbundle #-}-  default unbundle :: (Unbundled domain a ~ Signal domain a)-                   => Signal domain a -> Unbundled domain a+  default unbundle :: (Unbundled dom a ~ Signal dom a)+                   => Signal dom a -> Unbundled dom a   unbundle s = s +instance Bundle () instance Bundle Bool instance Bundle Integer instance Bundle Int@@ -123,21 +126,11 @@ instance Bundle (Signed n) instance Bundle (Unsigned n) --- | Note that:------ > bundle   :: () -> Signal domain ()--- > unbundle :: Signal domain () -> ()-instance Bundle () where-  type Unbundled t () = t ::: ()-  -- ^ This is just to satisfy the injectivity annotation-  bundle   u = pure u-  unbundle _ = ()- deriveBundleTuples ''Bundle ''Unbundled 'bundle 'unbundle  instance KnownNat n => Bundle (Vec n a) where   type Unbundled t (Vec n a) = Vec n (Signal t a)-  -- The 'Traversable' instance of 'Vec' is not synthesisable, so we must+  -- The 'Traversable' instance of 'Vec' is not synthesizable, so we must   -- define 'bundle' as a primitive.   bundle   = vecBundle#   unbundle = sequenceA . fmap lazyV
src/Clash/Signal/Bundle/Internal.hs view
@@ -1,7 +1,9 @@+{-# LANGUAGE CPP             #-} {-# LANGUAGE TemplateHaskell #-}  module Clash.Signal.Bundle.Internal where +import           Clash.CPP             (maxTupleSize) import           Clash.Signal.Internal (Signal) import           Control.Monad         (replicateM) import           Data.List             (foldl')@@ -22,13 +24,13 @@   let bundleTy = ConT bundleTyName       signal   = ConT ''Signal -  allNames <- replicateM 62 (newName "a")-  tempNames <- replicateM 62 (newName "b")+  allNames <- replicateM maxTupleSize (newName "a")+  tempNames <- replicateM maxTupleSize (newName "b")   t <- newName "t"   x <- newName "x"   tup <- newName "tup" -  pure $ flip map [2..62] $ \tupleNum ->+  pure $ flip map [2..maxTupleSize] $ \tupleNum ->     let names = take tupleNum allNames         temps = take tupleNum tempNames         vars  = fmap VarT names@@ -38,11 +40,20 @@         instTy = AppT bundleTy $ tuple vars          -- Associated type Unbundled+#if MIN_VERSION_template_haskell(2,15,0)         unbundledTypeEq =+          TySynEqn Nothing+            ((ConT unbundledTyName `AppT`+                VarT t ) `AppT` tuple vars )+            $ tuple $ map (AppT (signal `AppT` VarT t)) vars+        unbundledType = TySynInstD unbundledTypeEq+#else+        unbundledTypeEq =           TySynEqn             [ VarT t, tuple vars ]             $ tuple $ map (AppT (signal `AppT` VarT t)) vars         unbundledType = TySynInstD unbundledTyName unbundledTypeEq+#endif          bundleLambda = LamE (map VarP temps) (TupE $ map VarE temps)         applicatives = VarE '(<$>) : repeat (VarE '(<*>))@@ -71,7 +82,7 @@             [ Clause                 [ VarP tup ]                 ( NormalB . TupE $-                    map +                    map                       (\n -> VarE 'fmap `AppE` unbundleLambda n `AppE` VarE tup)                       [0..tupleNum-1]                 )
src/Clash/Signal/Delayed.hs view
@@ -1,29 +1,44 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.+                  2019     , Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE CPP                 #-}-{-# LANGUAGE DataKinds           #-}-{-# LANGUAGE FlexibleContexts    #-}-{-# LANGUAGE KindSignatures      #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE CPP                  #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE KindSignatures       #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE TypeApplications     #-}+{-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE TypeOperators        #-}+{-# LANGUAGE UndecidableInstances #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif  {-# LANGUAGE Trustworthy #-} +{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise       #-}+ module Clash.Signal.Delayed   ( -- * Delay-annotated synchronous signals     DSignal   , delayed   , delayedI+  , delayN+  , delayI+  , delayedFold   , feedback     -- * Signal \<-\> DSignal conversion   , fromSignal   , toSignal-    -- * List \<-\> DSignal conversion (not synthesisable)+    -- * List \<-\> DSignal conversion (not synthesizable)   , dfromList     -- ** lazy versions   , dfromList_lazy@@ -33,51 +48,183 @@   ) where -import           Data.Default                  (Default)-import           GHC.TypeLits                  (KnownNat, type (+))+import           Data.Coerce                   (coerce)+import           Data.Kind                     (Type)+import           Data.Proxy                    (Proxy(..))+import           GHC.TypeLits+  (KnownNat, type (^), type (+), type (*), Nat)+import           Data.Singletons.Prelude       (Apply, TyFun, type (@@)) +import           Clash.Signal.Internal         (Domain)+import Clash.Signal.Delayed.Internal+  (DSignal(..), dfromList, dfromList_lazy, fromSignal, toSignal,+   unsafeFromSignal, antiDelay, feedback) import qualified Clash.Explicit.Signal.Delayed as E-import           Clash.Explicit.Signal.Delayed-  (DSignal, dfromList, dfromList_lazy, feedback, fromSignal, toSignal,-   unsafeFromSignal, antiDelay)-import            Clash.Sized.Vector           (Vec)-import            Clash.Signal-  (HiddenClockReset, hideClockReset)+import           Clash.Sized.Vector            (Vec, dtfold)+import           Clash.Signal+  (HiddenClockResetEnable , hideClockResetEnable, Signal, delay) +import           Clash.Promoted.Nat            (SNat (..), snatToInteger)+import           Clash.XException              (NFDataX)+ {- $setup >>> :set -XDataKinds -XTypeOperators -XTypeApplications -XFlexibleContexts >>> import Clash.Prelude->>> let delay3 = delayed (0 :> 0 :> 0 :> Nil)->>> let delay2 = delayedI :: HiddenClockReset domain gated synchronous => DSignal domain n Int -> DSignal domain (n + 2) Int+>>> let delay3 = delayed (-1 :> -1 :> -1 :> Nil)+>>> let delay2 = delayedI :: HiddenClockResetEnable dom  => Int -> DSignal dom n Int -> DSignal dom (n + 2) Int+>>> let delayN2 = delayN d2+>>> let delayI2 = delayI :: HiddenClockResetEnable dom  => Int -> DSignal dom n Int -> DSignal dom (n + 2) Int+>>> let countingSignals = Clash.Prelude.repeat (dfromList [0..]) :: Vec 4 (DSignal dom 0 Int) -}  -- | Delay a 'DSignal' for @d@ periods. -- -- @--- delay3 :: 'DSignal' n Int -> 'DSignal' (n + 3) Int--- delay3 = 'delayed' (0 ':>' 0 ':>' 0 ':>' 'Nil')+-- delay3+--   :: HiddenClockResetEnable dom+--   => 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 3) Int+-- delay3 = 'delayed' (-1 ':>' -1 ':>' -1 ':>' 'Nil') -- @ ----- >>> sampleN 6 (toSignal (delay3 (dfromList [1..])))--- [0,0,0,1,2,3]+-- >>> sampleN @System 7 (toSignal (delay3 (dfromList [0..])))+-- [-1,-1,-1,-1,1,2,3] delayed-  :: (KnownNat d, HiddenClockReset domain gated synchronous)+  :: ( KnownNat d+     , HiddenClockResetEnable dom+     , NFDataX a+     )   => Vec d a-  -> DSignal domain n a-  -> DSignal domain (n + d) a-delayed = hideClockReset E.delayed+  -> DSignal dom n a+  -> DSignal dom (n + d) a+delayed = hideClockResetEnable E.delayed --- | Delay a 'DSignal' for @m@ periods, where @m@ is derived from the context.+-- | Delay a 'DSignal' for @d@ periods, where @d@ is derived from the context. -- -- @--- delay2 :: 'DSignal' n Int -> 'DSignal' (n + 2) Int+-- delay2+--   :: HiddenClockResetEnable dom+--   => Int+--   -> 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 2) Int -- delay2 = 'delayedI' -- @ ----- >>> sampleN 6 (toSignal (delay2 (dfromList [1..])))--- [0,0,1,2,3,4]+-- >>> sampleN @System 7 (toSignal (delay2 (-1) (dfromList [0..])))+-- [-1,-1,-1,1,2,3,4]+--+-- Or @d@ can be specified using type application:+--+-- >>> :t delayedI @3+-- delayedI @3+--   :: (...+--       ...+--       ...+--       ...) =>+--      a -> DSignal dom n a -> DSignal dom (n + 3) a delayedI-  :: (Default a, KnownNat d, HiddenClockReset domain gated synchronous)-  => DSignal domain n a-  -> DSignal domain (n + d) a-delayedI = hideClockReset E.delayedI+  :: ( KnownNat d+     , NFDataX a+     , HiddenClockResetEnable dom  )+  => a+  -- ^ Initial value+  -> DSignal dom n a+  -> DSignal dom (n + d) a+delayedI = hideClockResetEnable E.delayedI++-- | Delay a 'DSignal' for @d@ cycles, the value at time 0..d-1 is /a/.+--+-- @+-- delay2+--   :: HiddenClockResetEnable dom+--   => Int+--   -> 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 2) Int+-- delay2 = 'delayN' d2+-- @+--+-- >>> printX $ sampleN @System 6 (toSignal (delayN2 (-1) (dfromList [1..])))+-- [-1,-1,1,2,3,4]+delayN+  :: forall dom  a d n+   . ( HiddenClockResetEnable dom+     , NFDataX a )+  => SNat d+  -> a+  -- ^ Initial value+  -> DSignal dom n a+  -> DSignal dom (n+d) a+delayN d dflt = coerce . go (snatToInteger d) . coerce @_ @(Signal dom a)+  where+    go 0 = id+    go i = delay dflt . go (i-1)++-- | Delay a 'DSignal' for @d@ cycles, where @d@ is derived from the context.+-- The value at time 0..d-1 is a default value.+--+-- @+-- delayI2+--   :: HiddenClockResetEnable dom+--   => Int+--   -> 'DSignal' dom n Int+--   -> 'DSignal' dom (n + 2) Int+-- delayI2 = 'delayI'+-- @+--+-- >>> sampleN @System 6 (toSignal (delayI2 (-1) (dfromList [1..])))+-- [-1,-1,1,2,3,4]+--+-- You can also use type application to do the same:+-- >>> sampleN @System 6 (toSignal (delayI @2 (-1) (dfromList [1..])))+-- [-1,-1,1,2,3,4]+delayI+  :: forall d n a dom+   . ( HiddenClockResetEnable dom+     , NFDataX a+     , KnownNat d )+  => a+  -- ^ Initial value+  -> DSignal dom n a+  -> DSignal dom (n+d) a+delayI dflt = delayN (SNat :: SNat d) dflt++data DelayedFold (dom :: Domain) (n :: Nat) (delay :: Nat) (a :: Type) (f :: TyFun Nat Type) :: Type+type instance Apply (DelayedFold dom n delay a) k = DSignal dom (n + (delay*k)) a++-- | Tree fold over a 'Vec' of 'DSignal's with a combinatorial function,+-- and delaying @delay@ cycles after each application.+-- Values at times 0..(delay*k)-1 are set to a default.+--+-- @+-- countingSignals :: Vec 4 (DSignal dom 0 Int)+-- countingSignals = repeat (dfromList [0..])+-- @+--+-- >>> printX $ sampleN @System 6 (toSignal (delayedFold d1 (-1) (+) countingSignals))+-- [-1,-2,0,4,8,12]+--+-- >>> printX $ sampleN @System 8 (toSignal (delayedFold d2 (-1) (*) countingSignals))+-- [-1,-1,1,1,0,1,16,81]+delayedFold+  :: forall dom  n delay k a+   . ( HiddenClockResetEnable dom+     , NFDataX a+     , KnownNat delay+     , KnownNat k )+  => SNat delay+  -- ^ Delay applied after each step+  -> a+  -- ^ Initial value+  -> (a -> a -> a)+  -- ^ Fold operation to apply+  -> Vec (2^k) (DSignal dom n a)+  -- ^ Vector input of size 2^k+  -> DSignal dom (n + (delay * k)) a+  -- ^ Output Signal delayed by (delay * k)+delayedFold _ dflt op = dtfold (Proxy :: Proxy (DelayedFold dom n delay a)) id go+  where+    go :: SNat l+       -> DelayedFold dom n delay a @@ l+       -> DelayedFold dom n delay a @@ l+       -> DelayedFold dom n delay a @@ (l+1)+    go SNat x y = delayI dflt (op <$> x <*> y)
+ src/Clash/Signal/Delayed/Bundle.hs view
@@ -0,0 +1,224 @@+{-|+  Copyright   :  (C) 2019, Myrtle Software Ltd.+                     2018, @blaxill+                     2018, QBayLogic B.V.+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE DefaultSignatures      #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE KindSignatures         #-}+{-# LANGUAGE NoImplicitPrelude      #-}+{-# LANGUAGE PolyKinds              #-}+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeFamilyDependencies #-}+{-# LANGUAGE TypeOperators          #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++module Clash.Signal.Delayed.Bundle (+  Bundle,+  Unbundled,+  bundle,+  unbundle,+  ) where++import           Control.Applicative           (liftA2)+import           GHC.TypeLits                  (KnownNat)+import           Prelude                       hiding (head, map, tail)++import           Clash.Signal.Internal         (Domain)+import           Clash.Signal.Delayed (DSignal, toSignal, unsafeFromSignal)+import qualified Clash.Signal.Bundle           as B++import           Clash.Sized.BitVector         (Bit, BitVector)+import           Clash.Sized.Fixed             (Fixed)+import           Clash.Sized.Index             (Index)+import           Clash.Sized.RTree             (RTree, lazyT)+import           Clash.Sized.Signed            (Signed)+import           Clash.Sized.Unsigned          (Unsigned)+import           Clash.Sized.Vector            (Vec, lazyV)++import           GHC.TypeLits                  (Nat)++-- | Isomorphism between a 'DSignal' of a product type+-- (e.g. a tuple) and a product type of 'DSignal's.+--+-- Instances of 'Bundle' must satisfy the following laws:+--+-- @+-- 'bundle' . 'unbundle' = 'id'+-- 'unbundle' . 'bundle' = 'id'+-- @+--+-- By default, 'bundle' and 'unbundle', are defined as the identity, that is,+-- writing:+--+-- @+-- data D = A | B+--+-- instance Bundle D+-- @+--+-- is the same as:+--+-- @+-- data D = A | B+--+-- instance Bundle D where+--   type 'Unbundled' dom delay D = 'DSignal' dom d D+--   'bundle'   _ s = s+--   'unbundle' _ s = s+-- @+--+class Bundle a where+  type Unbundled (dom :: Domain) (d :: Nat) a = res | res -> dom d a+  type Unbundled dom d a = DSignal dom d a++  -- | Example:+  --+  -- @+  -- __bundle__ :: ('DSignal' dom d a, 'DSignal' dom d b) -> 'DSignal' clk d (a,b)+  -- @+  --+  -- However:+  --+  -- @+  -- __bundle__ :: 'DSignal' dom 'Clash.Sized.BitVector.Bit' -> 'DSignal' dom 'Clash.Sized.BitVector.Bit'+  -- @+  bundle :: Unbundled dom d a -> DSignal dom d a+  {-# INLINE bundle #-}+  default bundle :: (DSignal dom d a ~ Unbundled dom d a)+                 => Unbundled dom d a -> DSignal dom d a+  bundle s = s+  -- | Example:+  --+  -- @+  -- __unbundle__ :: 'DSignal' dom d (a,b) -> ('DSignal' dom d a, 'DSignal' dom d b)+  -- @+  --+  -- However:+  --+  -- @+  -- __unbundle__ :: 'DSignal' dom 'Clash.Sized.BitVector.Bit' -> 'DSignal' dom 'Clash.Sized.BitVector.Bit'+  -- @+  unbundle :: DSignal dom d a -> Unbundled dom d a+  {-# INLINE unbundle #-}+  default unbundle :: (Unbundled dom d a ~ DSignal dom d a)+                   => DSignal dom d a -> Unbundled dom d a+  unbundle s = s++instance Bundle ()+instance Bundle Bool+instance Bundle Integer+instance Bundle Int+instance Bundle Float+instance Bundle Double+instance Bundle (Maybe a)+instance Bundle (Either a b)++instance Bundle Bit+instance Bundle (BitVector n)+instance Bundle (Index n)+instance Bundle (Fixed rep int frac)+instance Bundle (Signed n)+instance Bundle (Unsigned n)++instance Bundle (a,b) where+  type Unbundled t delay (a,b) = (DSignal t delay a, DSignal t delay b)++  bundle       = uncurry (liftA2 (,))+  unbundle tup = (fmap fst tup, fmap snd tup)++instance Bundle (a,b,c) where+  type Unbundled t delay (a,b,c) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c)++  bundle   (a,b,c) = (,,) <$> a <*> b <*> c+  unbundle tup     = (fmap (\(x,_,_) -> x) tup+                      ,fmap (\(_,x,_) -> x) tup+                      ,fmap (\(_,_,x) -> x) tup+                      )+instance Bundle (a,b,c,d) where+  type Unbundled t delay (a,b,c,d) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d)++  bundle   (a,b,c,d) = (,,,) <$> a <*> b <*> c <*> d+  unbundle tup     = (fmap (\(x,_,_,_) -> x) tup+                      ,fmap (\(_,x,_,_) -> x) tup+                      ,fmap (\(_,_,x,_) -> x) tup+                      ,fmap (\(_,_,_,x) -> x) tup+                      )++instance Bundle (a,b,c,d,e) where+  type Unbundled t delay (a,b,c,d,e) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d+    , DSignal t delay e)++  bundle   (a,b,c,d,e) = (,,,,) <$> a <*> b <*> c <*> d <*> e+  unbundle tup     = (fmap (\(x,_,_,_,_) -> x) tup+                      ,fmap (\(_,x,_,_,_) -> x) tup+                      ,fmap (\(_,_,x,_,_) -> x) tup+                      ,fmap (\(_,_,_,x,_) -> x) tup+                      ,fmap (\(_,_,_,_,x) -> x) tup+                      )++instance Bundle (a,b,c,d,e,f) where+  type Unbundled t delay (a,b,c,d,e,f) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d+    , DSignal t delay e, DSignal t delay f)++  bundle   (a,b,c,d,e,f) = (,,,,,) <$> a <*> b <*> c <*> d <*> e <*> f+  unbundle tup           = (fmap (\(x,_,_,_,_,_) -> x) tup+                           ,fmap (\(_,x,_,_,_,_) -> x) tup+                           ,fmap (\(_,_,x,_,_,_) -> x) tup+                           ,fmap (\(_,_,_,x,_,_) -> x) tup+                           ,fmap (\(_,_,_,_,x,_) -> x) tup+                           ,fmap (\(_,_,_,_,_,x) -> x) tup+                           )++instance Bundle (a,b,c,d,e,f,g) where+  type Unbundled t delay (a,b,c,d,e,f,g) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d+    , DSignal t delay e, DSignal t delay f, DSignal t delay g)++  bundle   (a,b,c,d,e,f,g) = (,,,,,,) <$> a <*> b <*> c <*> d <*> e <*> f+                                      <*> g+  unbundle tup             = (fmap (\(x,_,_,_,_,_,_) -> x) tup+                             ,fmap (\(_,x,_,_,_,_,_) -> x) tup+                             ,fmap (\(_,_,x,_,_,_,_) -> x) tup+                             ,fmap (\(_,_,_,x,_,_,_) -> x) tup+                             ,fmap (\(_,_,_,_,x,_,_) -> x) tup+                             ,fmap (\(_,_,_,_,_,x,_) -> x) tup+                             ,fmap (\(_,_,_,_,_,_,x) -> x) tup+                             )++instance Bundle (a,b,c,d,e,f,g,h) where+  type Unbundled t delay (a,b,c,d,e,f,g,h) =+    ( DSignal t delay a, DSignal t delay b, DSignal t delay c, DSignal t delay d+    , DSignal t delay e, DSignal t delay f ,DSignal t delay g, DSignal t delay h)++  bundle   (a,b,c,d,e,f,g,h) = (,,,,,,,) <$> a <*> b <*> c <*> d <*> e <*> f+                                         <*> g <*> h+  unbundle tup               = (fmap (\(x,_,_,_,_,_,_,_) -> x) tup+                               ,fmap (\(_,x,_,_,_,_,_,_) -> x) tup+                               ,fmap (\(_,_,x,_,_,_,_,_) -> x) tup+                               ,fmap (\(_,_,_,x,_,_,_,_) -> x) tup+                               ,fmap (\(_,_,_,_,x,_,_,_) -> x) tup+                               ,fmap (\(_,_,_,_,_,x,_,_) -> x) tup+                               ,fmap (\(_,_,_,_,_,_,x,_) -> x) tup+                               ,fmap (\(_,_,_,_,_,_,_,x) -> x) tup+                               )++instance KnownNat n => Bundle (Vec n a) where+  type Unbundled t d (Vec n a) = Vec n (DSignal t d a)+  bundle   = unsafeFromSignal . B.bundle . fmap toSignal+  unbundle = sequenceA . fmap lazyV++instance KnownNat d => Bundle (RTree d a) where+  type Unbundled t delay (RTree d a) = RTree d (DSignal t delay a)+  bundle   = sequenceA+  unbundle = sequenceA . fmap lazyT
+ src/Clash/Signal/Delayed/Internal.hs view
@@ -0,0 +1,157 @@+{-|+  Copyright   :  (C) 2019     , Myrtle Software Ltd.+                     2018     , @blaxill+                     2018-2019, QBayLogic B.V.+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveLift                 #-}+{-# LANGUAGE DeriveTraversable          #-}+{-# LANGUAGE GADTs                      #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures             #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeOperators              #-}+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# LANGUAGE Trustworthy #-}++{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}+{-# OPTIONS_HADDOCK show-extensions #-}++module Clash.Signal.Delayed.Internal+  ( -- * Delay-annotated synchronous signals+    DSignal(..)+  , feedback+  , fromSignal+    -- * List \<-\> DSignal conversion (not synthesizable)+  , dfromList+    -- ** lazy versions+  , dfromList_lazy+    -- * Experimental+  , unsafeFromSignal+  , antiDelay+  )+where++import Data.Coerce                (coerce)+import Data.Default.Class         (Default(..))+import GHC.TypeLits               (Nat, type (+))+import Language.Haskell.TH.Syntax (Lift)+import Test.QuickCheck            (Arbitrary, CoArbitrary)++import Clash.Promoted.Nat         (SNat)+import Clash.Signal.Internal      (Domain)+import Clash.Explicit.Signal+  (Signal, fromList, fromList_lazy)+import Clash.XException           (NFDataX)++{- $setup+>>> :set -XDataKinds+>>> :set -XTypeOperators+>>> import Clash.Explicit.Prelude+>>> :{+let mac :: Clock System+        -> Reset System+        -> Enable System+        -> DSignal System 0 Int -> DSignal System 0 Int+        -> DSignal System 0 Int+    mac clk rst en x y = feedback (mac' x y)+      where+        mac' :: DSignal System 0 Int -> DSignal System 0 Int+             -> DSignal System 0 Int+             -> (DSignal System 0 Int, DSignal System 1 Int)+        mac' a b acc = let acc' = a * b + acc+                       in  (acc, delayed clk rst en (singleton 0) acc')+:}++-}++-- | A synchronized signal with samples of type @a@, synchronized to clock+-- @clk@, that has accumulated @delay@ amount of samples delay along its path.+newtype DSignal (dom :: Domain) (delay :: Nat) a =+    DSignal { toSignal :: Signal dom a+              -- ^ Strip a 'DSignal' from its delay information.+            }+  deriving ( Show, Default, Functor, Applicative, Num, Fractional+           , Foldable, Traversable, Arbitrary, CoArbitrary, Lift )++-- | Create a 'DSignal' from a list+--+-- Every element in the list will correspond to a value of the signal for one+-- clock cycle.+--+-- >>> sampleN 2 (dfromList [1,2,3,4,5])+-- [1,2]+--+-- __NB__: This function is not synthesizable+dfromList :: NFDataX a => [a] -> DSignal dom 0 a+dfromList = coerce . fromList++-- | Create a 'DSignal' from a list+--+-- Every element in the list will correspond to a value of the signal for one+-- clock cycle.+--+-- >>> sampleN 2 (dfromList [1,2,3,4,5])+-- [1,2]+--+-- __NB__: This function is not synthesizable+dfromList_lazy :: [a] -> DSignal dom 0 a+dfromList_lazy = coerce . fromList_lazy++-- | Feed the delayed result of a function back to its input:+--+-- @+-- mac :: Clock dom -> Reset dom -> Enable dom+--     -> 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int+-- mac clk rst en x y = 'feedback' (mac' x y)+--   where+--     mac' :: 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int+--          -> ('DSignal' dom 0 Int, 'DSignal' dom 1 Int)+--     mac' a b acc = let acc' = a * b + acc+--                    in  (acc, 'delay' clk rst en ('singleton' 0) acc')+-- @+--+-- >>> sampleN 7 (mac systemClockGen systemResetGen enableGen (dfromList [0..]) (dfromList [0..]))+-- [0,0,1,5,14,30,55]+feedback+  :: (DSignal dom n a -> (DSignal dom n a,DSignal dom (n + m + 1) a))+  -> DSignal dom n a+feedback f = let (o,r) = f (coerce r) in o++-- | 'Signal's are not delayed+--+-- > sample s == dsample (fromSignal s)+fromSignal :: Signal dom a -> DSignal dom 0 a+fromSignal = coerce++-- | __EXPERIMENTAL__+--+-- __Unsafely__ convert a 'Signal' to /any/ 'DSignal' clk'.+--+-- __NB__: Should only be used to interface with functions specified in terms of+-- 'Signal'.+unsafeFromSignal :: Signal dom a -> DSignal dom n a+unsafeFromSignal = DSignal++-- | __EXPERIMENTAL__+--+-- Access a /delayed/ signal in the present.+--+-- @+-- mac :: Clock dom -> Reset dom -> Enable dom+--     -> 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int -> 'DSignal' dom 0 Int+-- mac clk rst en x y = acc'+--   where+--     acc' = (x * y) + 'antiDelay' d1 acc+--     acc  = 'delay' clk rst en ('singleton' 0) acc'+-- @+antiDelay :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a+antiDelay _ = coerce
src/Clash/Signal/Internal.hs view
@@ -1,842 +1,1365 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2017     , Myrtle Software Ltd, Google Inc.-License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>--}--{-# LANGUAGE CPP                   #-}-{-# LANGUAGE DataKinds             #-}-{-# LANGUAGE DeriveAnyClass        #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE GADTs                 #-}-{-# LANGUAGE KindSignatures        #-}-{-# LANGUAGE MagicHash             #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables   #-}-{-# LANGUAGE TemplateHaskell       #-}-{-# LANGUAGE TypeFamilies          #-}--{-# LANGUAGE Unsafe #-}---- See: https://github.com/clash-lang/clash-compiler/commit/721fcfa9198925661cd836668705f817bddaae3c--- as to why we need this.-{-# OPTIONS_GHC -fno-cpr-anal #-}--{-# OPTIONS_HADDOCK show-extensions not-home #-}--module Clash.Signal.Internal-  ( -- * Datatypes-    Domain (..)-  , Signal (..)-    -- * Clocks-  , Clock (..)-  , ClockKind (..)-  , clockPeriod-  , clockEnable-    -- ** Clock gating-  , clockGate-    -- * Resets-  , Reset (..)-  , ResetKind (..)-  , unsafeFromAsyncReset-  , unsafeToAsyncReset-  , fromSyncReset-  , unsafeToSyncReset-    -- * Basic circuits-  , delay#-  , register#-  , mux-    -- * Simulation and testbench functions-  , clockGen-  , tbClockGen-  , asyncResetGen-  , syncResetGen-    -- * Boolean connectives-  , (.&&.), (.||.)-    -- * Simulation functions (not synthesisable)-  , simulate-    -- ** lazy version-  , simulate_lazy-    -- * List \<-\> Signal conversion (not synthesisable)-  , sample-  , sampleN-  , fromList-    -- ** lazy versions-  , sample_lazy-  , sampleN_lazy-  , fromList_lazy-    -- * QuickCheck combinators-  , testFor-    -- * Type classes-    -- ** 'Eq'-like-  , (.==.), (./=.)-    -- ** 'Ord'-like-  , (.<.), (.<=.), (.>=.), (.>.)-    -- ** 'Functor'-  , mapSignal#-    -- ** 'Applicative'-  , signal#-  , appSignal#-    -- ** 'Foldable'-  , foldr#-    -- ** 'Traversable'-  , traverse#-  -- * EXTREMELY EXPERIMENTAL-  , joinSignal#-  )-where--import Control.Applicative        (liftA2, liftA3)-import Control.DeepSeq            (NFData, force)-import Control.Exception          (catch, evaluate, throw)-import Data.Default               (Default (..))-import GHC.Generics               (Generic)-import GHC.Stack                  (HasCallStack, withFrozenCallStack)-import GHC.TypeLits               (KnownNat, KnownSymbol, Nat, Symbol)-import Language.Haskell.TH.Syntax (Lift (..))-import System.IO.Unsafe           (unsafeDupablePerformIO)-import Test.QuickCheck            (Arbitrary (..), CoArbitrary(..), Property,-                                   property)--import Clash.Promoted.Nat         (SNat (..), snatToInteger, snatToNum)-import Clash.Promoted.Symbol      (SSymbol (..))-import Clash.XException           (XException, errorX, seqX)--{- $setup->>> :set -XDataKinds->>> :set -XMagicHash->>> :set -XTypeApplications->>> import Clash.Promoted.Nat->>> import Clash.XException->>> type System = Dom "System" 10000->>> let systemClockGen = clockGen @System->>> let systemResetGen = asyncResetGen @System->>> let register = register#->>> let registerS = register#->>> let registerA = register#--}---- * Signal---- | A domain with a name (@Symbol@) and a clock period (@Nat@) in /ps/-data Domain = Dom { domainName :: Symbol, clkPeriod :: Nat }--infixr 5 :--{- | CλaSH has synchronous 'Signal's in the form of:--@-'Signal' (domain :: 'Domain') a-@--Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,-and /domain/ is the /clock-/ (and /reset-/) domain to which the memory elements-manipulating these 'Signal's belong.--The type-parameter, /domain/, is of the kind 'Domain' which has types of the-following shape:--@-data Domain = Dom { domainName :: 'GHC.TypeLits.Symbol', clkPeriod :: 'GHC.TypeLits.Nat' }-@--Where /domainName/ is a type-level string ('GHC.TypeLits.Symbol') representing-the name of the /clock-/ (and /reset-/) domain, and /clkPeriod/ is a type-level-natural number ('GHC.TypeLits.Nat') representing the clock period (in __ps__)-of the clock lines in the /clock-domain/.--* __NB__: \"Bad things\"™  happen when you actually use a clock period of @0@,-so do __not__ do that!-* __NB__: You should be judicious using a clock with period of @1@ as you can-never create a clock that goes any faster!--}-data Signal (domain :: Domain) a-  -- | The constructor, @(':-')@, is __not__ synthesisable.-  = a :- Signal domain a--instance Show a => Show (Signal domain a) where-  show (x :- xs) = show x ++ " " ++ show xs--instance Lift a => Lift (Signal domain a) where-  lift ~(x :- _) = [| signal# x |]--instance Default a => Default (Signal domain a) where-  def = signal# def--instance Functor (Signal domain) where-  fmap = mapSignal#--{-# NOINLINE mapSignal# #-}-mapSignal# :: (a -> b) -> Signal domain a -> Signal domain b-mapSignal# f (a :- as) = f a :- mapSignal# f as--instance Applicative (Signal domain) where-  pure  = signal#-  (<*>) = appSignal#--{-# NOINLINE signal# #-}-signal# :: a -> Signal domain a-signal# a = let s = a :- s in s--{-# NOINLINE appSignal# #-}-appSignal# :: Signal domain (a -> b) -> Signal domain a -> Signal domain b-appSignal# (f :- fs) xs@(~(a :- as)) = f a :- (xs `seq` appSignal# fs as) -- See [NOTE: Lazy ap]--{- NOTE: Lazy ap-Signal's ap, i.e (Applicative.<*>), must be lazy in it's second argument:--> appSignal :: Signal' clk (a -> b) -> Signal' clk a -> Signal' clk b-> appSignal (f :- fs) ~(a :- as) = f a :- appSignal fs as--because some feedback loops, such as the loop described in 'system' in the-example at http://hackage.haskell.org/package/clash-prelude-0.10.10/docs/Clash-Prelude-BlockRam.html,-will lead to "Exception <<loop>>".--However, this "naive" lazy version is _too_ lazy and induces spaceleaks.-The current version:--> appSignal# :: Signal' clk (a -> b) -> Signal' clk a -> Signal' clk b-> appSignal# (f :- fs) xs@(~(a :- as)) = f a :- (xs `seq` appSignal# fs as)--Is lazy enough to handle the earlier mentioned feedback loops, but doesn't leak-(as much) memory like the "naive" lazy version, because the Signal constructor-of the second argument is evaluated as soon as the tail of the result is evaluated.--}---{-# NOINLINE joinSignal# #-}--- | __WARNING: EXTREMELY EXPERIMENTAL__------ The circuit semantics of this operation are unclear and/or non-existent.--- There is a good reason there is no 'Monad' instance for 'Signal''.------ Is currently treated as 'id' by the Clash compiler.-joinSignal# :: Signal domain (Signal domain a) -> Signal domain a-joinSignal# ~(xs :- xss) = head# xs :- joinSignal# (mapSignal# tail# xss)-  where-    head# (x' :- _ )  = x'-    tail# (_  :- xs') = xs'--instance Num a => Num (Signal domain a) where-  (+)         = liftA2 (+)-  (-)         = liftA2 (-)-  (*)         = liftA2 (*)-  negate      = fmap negate-  abs         = fmap abs-  signum      = fmap signum-  fromInteger = signal# . fromInteger---- | __NB__: Not synthesisable------ __NB__: In \"@'foldr' f z s@\":------ * The function @f@ should be /lazy/ in its second argument.--- * The @z@ element will never be used.-instance Foldable (Signal domain) where-  foldr = foldr#--{-# NOINLINE foldr# #-}--- | __NB__: Not synthesisable------ __NB__: In \"@'foldr#' f z s@\":------ * The function @f@ should be /lazy/ in its second argument.--- * The @z@ element will never be used.-foldr# :: (a -> b -> b) -> b -> Signal domain a -> b-foldr# f z (a :- s) = a `f` (foldr# f z s)--instance Traversable (Signal domain) where-  traverse = traverse#--{-# NOINLINE traverse# #-}-traverse# :: Applicative f => (a -> f b) -> Signal domain a -> f (Signal domain b)-traverse# f (a :- s) = (:-) <$> f a <*> traverse# f s---- * Clocks and resets---- | Distinction between gated and ungated clocks-data ClockKind-  = Source -- ^ A clock signal coming straight from the clock source-  | Gated  -- ^ A clock signal that has been gated-  deriving (Eq,Ord,Show,Generic,NFData)---- | A clock signal belonging to a @domain@-data Clock (domain :: Domain) (gated :: ClockKind) where-  Clock-    :: (domain ~ ('Dom name period))-    => SSymbol name-    -> SNat    period-    -> Clock domain 'Source-  GatedClock-    :: (domain ~ ('Dom name period))-    => SSymbol name-    -> SNat    period-    -> Signal domain Bool-    -> Clock  domain 'Gated---- | Get the clock period of a 'Clock' (in /ps/) as a 'Num'-clockPeriod-  :: Num a-  => Clock domain gated-  -> a-clockPeriod (Clock _ period)        = snatToNum period-clockPeriod (GatedClock _ period _) = snatToNum period---- | If the clock is gated, return 'Just' the /enable/ signal, 'Nothing'--- otherwise-clockEnable-  :: Clock domain gated-  -> Maybe (Signal domain Bool)-clockEnable Clock {}            = Nothing-clockEnable (GatedClock _ _ en) = Just en--instance Show (Clock domain gated) where-  show (Clock      nm period)   = show nm ++ show (snatToInteger period)-  show (GatedClock nm period _) = show nm ++ show (snatToInteger period)---- | Clock gating primitive-clockGate :: Clock domain gated -> Signal domain Bool -> Clock domain 'Gated-clockGate (Clock nm rt)         en  = GatedClock nm rt en-clockGate (GatedClock nm rt en) en' = GatedClock nm rt (en .&&. en')-{-# NOINLINE clockGate #-}---- | Clock generator for simulations. Do __not__ use this clock generator for--- for the /testBench/ function, use 'tbClockGen' instead.------ To be used like:------ @--- type DomA = Dom \"A\" 1000--- clkA = clockGen @DomA--- @-clockGen-  :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period)-  => Clock domain 'Source-clockGen = Clock SSymbol SNat-{-# NOINLINE clockGen #-}---- | Clock generator to be used in the /testBench/ function.------ To be used like:------ @--- type DomA = Dom \"A\" 1000--- clkA en = clockGen @DomA en--- @------ === __Example__------ @--- type DomA1 = Dom \"A\" 1 -- fast, twice as fast as slow--- type DomB2 = Dom \"B\" 2 -- slow------ topEntity---   :: Clock DomA1 Source---   -> Reset DomA1 Asynchronous---   -> Clock DomB2 Source---   -> Signal DomA1 (Unsigned 8)---   -> Signal DomB2 (Unsigned 8, Unsigned 8)--- topEntity clk1 rst1 clk2 i =---   let h = register clk1 rst1 0 (register clk1 rst1 0 i)---       l = register clk1 rst1 0 i---   in  unsafeSynchronizer clk1 clk2 (bundle (h,l))------ testBench---   :: Signal DomB2 Bool--- testBench = done---   where---     testInput      = stimuliGenerator clkA1 rstA1 $(listToVecTH [1::Unsigned 8,2,3,4,5,6,7,8])---     expectedOutput = outputVerifier   clkB2 rstB2 $(listToVecTH [(0,0) :: (Unsigned 8, Unsigned 8),(1,2),(3,4),(5,6),(7,8)])---     done           = expectedOutput (topEntity clkA1 rstA1 clkB2 testInput)---     done'          = not \<$\> done---     clkA1          = 'tbClockGen' \@DomA1 (unsafeSynchronizer clkB2 clkA1 done')---     clkB2          = 'tbClockGen' \@DomB2 done'---     rstA1          = asyncResetGen \@DomA1---     rstB2          = asyncResetGen \@DomB2--- @-tbClockGen-  :: (domain ~ 'Dom nm period, KnownSymbol nm, KnownNat period)-  => Signal domain Bool-  -> Clock domain 'Source-tbClockGen _ = Clock SSymbol SNat-{-# NOINLINE tbClockGen #-}---- | Asynchronous reset generator, for simulations and the /testBench/ function.------ To be used like:------ @--- type DomA = Dom \"A\" 1000--- rstA = asyncResetGen @DomA--- @------ __NB__: Can only be used for components with an /active-high/ reset--- port, which all __clash-prelude__ components are.------ === __Example__------ @--- type Dom2 = Dom "dom" 2--- type Dom7 = Dom "dom" 7--- type Dom9 = Dom "dom" 9------ topEntity---   :: Clock Dom2 Source---   -> Clock Dom7 Source---   -> Clock Dom9 Source---   -> Signal Dom7 Integer---   -> Signal Dom9 Integer--- topEntity clk2 clk7 clk9 i = delay clk9 (unsafeSynchronizer clk2 clk9 (delay clk2 (unsafeSynchronizer clk7 clk2 (delay clk7 i))))--- {-# NOINLINE topEntity #-}------ testBench---   :: Signal Dom9 Bool--- testBench = done---   where---     testInput      = stimuliGenerator clk7 rst7 $(listToVecTH [(1::Integer)..10])---     expectedOutput = outputVerifier   clk9 rst9---                         ((undefined :> undefined :> Nil) ++ $(listToVecTH ([2,3,4,5,7,8,9,10]::[Integer])))---     done           = expectedOutput (topEntity clk2 clk7 clk9 testInput)---     done'          = not \<$\> done---     clk2           = tbClockGen \@Dom2 (unsafeSynchronizer clk9 clk2 done')---     clk7           = tbClockGen \@Dom7 (unsafeSynchronizer clk9 clk7 done')---     clk9           = tbClockGen \@Dom9 done'---     rst7           = 'asyncResetGen' \@Dom7---     rst9           = 'asyncResetGen' \@Dom9--- @-asyncResetGen :: Reset domain 'Asynchronous-asyncResetGen = Async (True :- pure False)-{-# NOINLINE asyncResetGen #-}---- | Synchronous reset generator, for simulations and the /testBench/ function.------ To be used like:------ @--- type DomA = Dom \"A\" 1000--- rstA = syncResetGen @DomA--- @------ __NB__: Can only be used for components with an /active-high/ reset--- port, which all __clash-prelude__ components are.-syncResetGen :: ( domain ~ 'Dom n clkPeriod-                , KnownNat clkPeriod )-             => Reset domain 'Synchronous-syncResetGen = Sync (True :- pure False)-{-# NOINLINE syncResetGen #-}---- | The \"kind\" of reset------ Given a situation where a reset is asserted, and then de-asserted at the--- active flank of the clock, we can observe the difference between a--- synchronous reset and an asynchronous reset:------ === Synchronous reset------ > registerS--- >   :: Clock domain gated -> Reset domain Synchronous--- >   -> Signal domain Int -> Signal domain Int--- > registerS = register------ >>> printX (sampleN 4 (registerS (clockGen @System) (syncResetGen @System) 0 (fromList [1,2,3])))--- [X,0,2,3]------ === Asynchronous reset------ > registerA--- >   :: Clock domain gated -> Reset domain Asynchronous--- >   -> Signal domain Int -> Signal domain Int--- > registerA = register------ >>> sampleN 4 (registerA (clockGen @System) (asyncResetGen @System) 0 (fromList [1,2,3]))--- [0,1,2,3]-data ResetKind-  = Synchronous-  -- ^ Components with a synchronous reset port produce the reset value when:-  ---  --     * The reset is asserted during the active flank of the clock to which-  --       the component is synchronized.-  | Asynchronous-  -- ^ Components with an asynchronous reset port produce the reset value when:-  ---  --     * Immediately when the reset is asserted.-  deriving (Eq,Ord,Show,Generic,NFData)---- | A reset signal belonging to a @domain@.------ The underlying representation of resets is 'Bool'. Note that all components--- in the __clash-prelude__ package have an /active-high/ reset port, i.e., the--- component is reset when the reset port is 'True'.-data Reset (domain :: Domain) (synchronous :: ResetKind) where-  Sync  :: Signal domain Bool -> Reset domain 'Synchronous-  Async :: Signal domain Bool -> Reset domain 'Asynchronous---- | 'unsafeFromAsyncReset' is unsafe because it can introduce:------ * <Clash-Explicit-Signal.html#metastability meta-stability>-unsafeFromAsyncReset :: Reset domain 'Asynchronous -> Signal domain Bool-unsafeFromAsyncReset (Async r) = r-{-# NOINLINE unsafeFromAsyncReset #-}---- | 'unsafeToAsyncReset' is unsafe because it can introduce:------ * combinational loops------ === __Example__------ @--- resetSynchronizer---   :: Clock domain gated---   -> Reset domain 'Asynchronous---   -> Reset domain 'Asynchronous--- resetSynchronizer clk rst  =---   let r1 = register clk rst True (pure False)---       r2 = register clk rst True r1---   in  'unsafeToAsyncReset' r2--- @-unsafeToAsyncReset :: Signal domain Bool -> Reset domain 'Asynchronous-unsafeToAsyncReset r = Async r-{-# NOINLINE unsafeToAsyncReset #-}---- | It is safe to treat synchronous resets as @Bool@ signals-fromSyncReset :: Reset domain 'Synchronous -> Signal domain Bool-fromSyncReset (Sync r) = r-{-# NOINLINE fromSyncReset #-}---- | 'unsafeToSyncReset' is unsafe because:------ * It can lead to <Clash-Explicit-Signal.html#metastability meta-stability>--- issues in the presence of asynchronous resets.-unsafeToSyncReset :: Signal domain Bool -> Reset domain 'Synchronous-unsafeToSyncReset r = Sync r-{-# NOINLINE unsafeToSyncReset #-}--infixr 2 .||.--- | The above type is a generalisation for:------ @--- __(.||.)__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('||') that returns a 'Clash.Signal.Signal' of 'Bool'-(.||.) :: Applicative f => f Bool -> f Bool -> f Bool-(.||.) = liftA2 (||)--infixr 3 .&&.--- | The above type is a generalisation for:------ @--- __(.&&.)__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('&&') that returns a 'Clash.Signal.Signal' of 'Bool'-(.&&.) :: Applicative f => f Bool -> f Bool -> f Bool-(.&&.) = liftA2 (&&)---- [Note: register strictness annotations]------ In order to produce the first (current) value of the register's output--- signal, 'o', we don't need to know the shape of either input (enable or--- value-in).  This is important, because both values might be produced from--- the output in a feedback loop, so we can't know their shape (pattern--- match) them until we have produced output.------ Thus, we use lazy pattern matching to delay inspecting the shape of--- either argument until output has been produced.------ However, both arguments need to be evaluated to WHNF as soon as possible--- to avoid a space-leak.  Below, we explicitly reduce the value-in signal--- using 'seq' as the tail of our output signal is produced.  On the other--- hand, because the value of the tail depends on the value of the enable--- signal 'e', it will be forced by the 'if'/'then' statement and we don't--- need to 'seq' it explicitly.--delay#-  :: HasCallStack-  => Clock  domain gated-  -> Signal domain a-  -> Signal domain a-delay# Clock {} =-  \s -> withFrozenCallStack (errorX "delay: initial value undefined") :- s--delay# (GatedClock _ _ en) =-    go (withFrozenCallStack (errorX "delay: initial value undefined")) en-  where-    go o (e :- es) as@(~(x :- xs)) =-      -- See [Note: register strictness annotations]-      o `seqX` o :- (as `seq` if e then go x es xs else go o es xs)-{-# NOINLINE delay# #-}--register#-  :: HasCallStack-  => Clock domain gated-  -> Reset domain synchronous-  -> a-  -> Signal domain a-  -> Signal domain a-register# Clock {} (Sync rst) i =-    go (withFrozenCallStack (errorX "register: initial value undefined")) rst-  where-    go o rt@(~(r :- rs)) as@(~(x :- xs)) =-      let o' = if r then i else x-          -- [Note: register strictness annotations]-      in  o `seqX` o :- (rt `seq` as `seq` go o' rs xs)--register# Clock {} (Async rst) i =-    go (withFrozenCallStack (errorX "register: initial value undefined")) rst-  where-    go o (r :- rs) as@(~(x :- xs)) =-      let o' = if r then i else o-          -- [Note: register strictness annotations]-      in  o' `seqX` o' :- (as `seq` go x rs xs)--register# (GatedClock _ _ ena) (Sync rst)  i =-    go (withFrozenCallStack (errorX "register: initial value undefined")) rst ena-  where-    go o rt@(~(r :- rs)) enas@(~(e :- es)) as@(~(x :- xs)) =-      let oE = if e then x else o-          oR = if r then i else oE-          -- [Note: register strictness annotations]-      in  o `seqX` o :- (rt `seq` enas `seq` as `seq` go oR rs es xs)--register# (GatedClock _ _ ena) (Async rst) i =-    go (withFrozenCallStack (errorX "register: initial value undefined")) rst ena-  where-    go o (r :- rs) enas@(~(e :- es)) as@(~(x :- xs)) =-      let oR = if r then i else o-          oE = if e then x else oR-          -- [Note: register strictness annotations]-      in  oR `seqX` oR :- (as `seq` enas `seq` go oE rs es xs)-{-# NOINLINE register# #-}--{-# INLINE mux #-}--- | The above type is a generalisation for:------ @--- __mux__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a--- @------ A multiplexer. Given "@'mux' b t f@", output @t@ when @b@ is 'True', and @f@--- when @b@ is 'False'.-mux :: Applicative f => f Bool -> f a -> f a -> f a-mux = liftA3 (\b t f -> if b then t else f)--infix 4 .==.--- | The above type is a generalisation for:------ @--- __(.==.)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('==') that returns a 'Clash.Signal.Signal' of 'Bool'-(.==.) :: (Eq a, Applicative f) => f a -> f a -> f Bool-(.==.) = liftA2 (==)--infix 4 ./=.--- | The above type is a generalisation for:------ @--- __(./=.)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('/=') that returns a 'Clash.Signal.Signal' of 'Bool'-(./=.) :: (Eq a, Applicative f) => f a -> f a -> f Bool-(./=.) = liftA2 (/=)--infix 4 .<.--- | The above type is a generalisation for:------ @--- __(.<.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('<') that returns a 'Clash.Signal.Signal' of 'Bool'-(.<.) :: (Ord a, Applicative f) => f a -> f a -> f Bool-(.<.) = liftA2 (<)--infix 4 .<=.--- | The above type is a generalisation for:------ @--- __(.<=.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('<=') that returns a 'Clash.Signal.Signal' of 'Bool'-(.<=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool-(.<=.) = liftA2 (<=)--infix 4 .>.--- | The above type is a generalisation for:------ @--- __(.>.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------ It is a version of ('>') that returns a 'Clash.Signal.Signal' of 'Bool'-(.>.) :: (Ord a, Applicative f) => f a -> f a -> f Bool-(.>.) = liftA2 (>)--infix 4 .>=.--- | The above type is a generalisation for:------ @--- __(.>=.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'--- @------  It is a version of ('>=') that returns a 'Clash.Signal.Signal' of 'Bool'-(.>=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool-(.>=.) = liftA2 (>=)--instance Fractional a => Fractional (Signal domain a) where-  (/)          = liftA2 (/)-  recip        = fmap recip-  fromRational = signal# . fromRational--instance Arbitrary a => Arbitrary (Signal domain a) where-  arbitrary = liftA2 (:-) arbitrary arbitrary--instance CoArbitrary a => CoArbitrary (Signal domain a) where-  coarbitrary xs gen = do-    n <- arbitrary-    coarbitrary (take (abs n) (sample_lazy xs)) gen---- | The above type is a generalisation for:------ @--- __testFor__ :: 'Int' -> 'Clash.Signal.Signal' Bool -> 'Property'--- @------ @testFor n s@ tests the signal @s@ for @n@ cycles.-testFor :: Foldable f => Int -> f Bool -> Property-testFor n = property . and . take n . sample---- * List \<-\> Signal conversion (not synthesisable)---- | A 'force' that lazily returns exceptions-forceNoException :: NFData a => a -> IO a-forceNoException x = catch (evaluate (force x)) (\(e :: XException) -> return (throw e))--headStrictCons :: NFData a => a -> [a] -> [a]-headStrictCons x xs = unsafeDupablePerformIO ((:) <$> forceNoException x <*> pure xs)--headStrictSignal :: NFData a => a -> Signal domain a -> Signal domain a-headStrictSignal x xs = unsafeDupablePerformIO ((:-) <$> forceNoException x <*> pure xs)---- | The above type is a generalisation for:------ @--- __sample__ :: 'Clash.Signal.Signal' a -> [a]--- @------ Get an infinite list of samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Clash.Signal.Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ __NB__: This function is not synthesisable-sample :: (Foldable f, NFData a) => f a -> [a]-sample = foldr headStrictCons []---- | The above type is a generalisation for:------ @--- __sampleN__ :: Int -> 'Clash.Signal.Signal' a -> [a]--- @------ Get a list of @n@ samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Clash.Signal.Signal'--- at consecutive clock cycles------ > sampleN 3 s == [s0, s1, s2]------ __NB__: This function is not synthesisable-sampleN :: (Foldable f, NFData a) => Int -> f a -> [a]-sampleN n = take n . sample---- | Create a 'Clash.Signal.Signal' from a list------ Every element in the list will correspond to a value of the signal for one--- clock cycle.------ >>> sampleN 2 (fromList [1,2,3,4,5])--- [1,2]------ __NB__: This function is not synthesisable-fromList :: NFData a => [a] -> Signal domain a-fromList = Prelude.foldr headStrictSignal (errorX "finite list")---- * Simulation functions (not synthesisable)---- | Simulate a (@'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' b@) function--- given a list of samples of type @a@------ >>> simulate (register systemClockGen systemResetGen 8) [1, 2, 3]--- [8,1,2,3...--- ...------ __NB__: This function is not synthesisable-simulate :: (NFData a, NFData b) => (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]-simulate f = sample . f . fromList---- | The above type is a generalisation for:------ @--- __sample__ :: 'Clash.Signal.Signal' a -> [a]--- @------ Get an infinite list of samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Clash.Signal.Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ __NB__: This function is not synthesisable-sample_lazy :: Foldable f => f a -> [a]-sample_lazy = foldr (:) []---- | The above type is a generalisation for:------ @--- __sampleN__ :: Int -> 'Clash.Signal.Signal' a -> [a]--- @------ Get a list of @n@ samples from a 'Clash.Signal.Signal'------ The elements in the list correspond to the values of the 'Clash.Signal.Signal'--- at consecutive clock cycles------ > sampleN 3 s == [s0, s1, s2]------ __NB__: This function is not synthesisable-sampleN_lazy :: Foldable f => Int -> f a -> [a]-sampleN_lazy n = take n . sample_lazy---- | Create a 'Clash.Signal.Signal' from a list------ Every element in the list will correspond to a value of the signal for one--- clock cycle.------ >>> sampleN 2 (fromList [1,2,3,4,5])--- [1,2]------ __NB__: This function is not synthesisable-fromList_lazy :: [a] -> Signal domain a-fromList_lazy = Prelude.foldr (:-) (error "finite list")---- * Simulation functions (not synthesisable)---- | Simulate a (@'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' b@) function--- given a list of samples of type @a@------ >>> simulate (register systemClockGen systemResetGen 8) [1, 2, 3]--- [8,1,2,3...--- ...------ __NB__: This function is not synthesisable-simulate_lazy :: (Signal domain1 a -> Signal domain2 b) -> [a] -> [b]-simulate_lazy f = sample_lazy . f . fromList_lazy+                  2017-2019, Myrtle Software Ltd+                  2017,      Google Inc.+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE ConstraintKinds        #-}+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE DataKinds              #-}+{-# LANGUAGE DeriveAnyClass         #-}+{-# LANGUAGE DeriveDataTypeable     #-}+{-# LANGUAGE DeriveGeneric          #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE MagicHash              #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE StandaloneDeriving     #-}+{-# LANGUAGE TemplateHaskell        #-}+{-# LANGUAGE TypeApplications       #-}+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeOperators          #-}+{-# LANGUAGE ViewPatterns           #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif+#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# LANGUAGE Unsafe #-}++{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}+{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}++-- See: https://github.com/clash-lang/clash-compiler/commit/721fcfa9198925661cd836668705f817bddaae3c+-- as to why we need this.+{-# OPTIONS_GHC -fno-cpr-anal #-}++{-# OPTIONS_HADDOCK show-extensions not-home #-}++module Clash.Signal.Internal+  ( -- * Datatypes+    Signal(..)+  , head#+  , tail#+    -- * Domains+  , Domain+  , KnownDomain(..)+  , KnownConfiguration+  , knownDomainByName+  , ActiveEdge(..)+  , SActiveEdge(..)+  , InitBehavior(..)+  , SInitBehavior(..)+  , ResetKind(..)+  , SResetKind(..)+  , ResetPolarity(..)+  , SResetPolarity(..)+  , DomainConfiguration(..)+  , SDomainConfiguration(..)+  -- ** Configuration type families+  , DomainPeriod+  , DomainActiveEdge+  , DomainResetKind+  , DomainInitBehavior+  , DomainResetPolarity+    -- ** Default domains+  , System+  , XilinxSystem+  , IntelSystem+  , vSystem+  , vIntelSystem+  , vXilinxSystem+    -- ** Domain utilities+  , VDomainConfiguration(..)+  , vDomain+  , createDomain+    -- * Clocks+  , Clock (..)+  , clockTag+  , hzToPeriod+  , periodToHz+    -- ** Enabling+  , Enable(..)+  , toEnable+  , fromEnable+  , enableGen+    -- * Resets+  , Reset(..)+  , unsafeToReset+  , unsafeFromReset+  , unsafeToHighPolarity+  , unsafeToLowPolarity+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+  , invertReset+    -- * Basic circuits+  , delay#+  , register#+  , mux+    -- * Simulation and testbench functions+  , clockGen+  , resetGen+  , resetGenN+    -- * Boolean connectives+  , (.&&.), (.||.)+    -- * Simulation functions (not synthesizable)+  , simulate+    -- ** lazy version+  , simulate_lazy+    -- * List \<-\> Signal conversion (not synthesizable)+  , sample+  , sampleN+  , fromList+    -- ** lazy versions+  , sample_lazy+  , sampleN_lazy+  , fromList_lazy+    -- * QuickCheck combinators+  , testFor+    -- * Type classes+    -- ** 'Eq'-like+  , (.==.), (./=.)+    -- ** 'Ord'-like+  , (.<.), (.<=.), (.>=.), (.>.)+    -- ** 'Functor'+  , mapSignal#+    -- ** 'Applicative'+  , signal#+  , appSignal#+    -- ** 'Foldable'+  , foldr#+    -- ** 'Traversable'+  , traverse#+  -- * EXTREMELY EXPERIMENTAL+  , joinSignal#+  )+where++import Type.Reflection            (Typeable)+import Control.Applicative        (liftA2, liftA3)+import Control.DeepSeq            (NFData)+import Clash.Annotations.Primitive (hasBlackBox)+import Data.Binary                (Binary)+import Data.Char                  (isAsciiUpper, isAlphaNum, isAscii)+import Data.Coerce                (coerce)+import Data.Data                  (Data)+import Data.Default.Class         (Default (..))+import Data.Hashable              (Hashable)+import Data.Proxy                 (Proxy(..))+import GHC.Generics               (Generic)+import GHC.Stack                  (HasCallStack)+import GHC.TypeLits               (KnownSymbol, Nat, Symbol, type (<=))+import Language.Haskell.TH.Syntax -- (Lift (..), Q, Dec)+import Language.Haskell.TH.Compat (mkTySynInstD)+import Numeric.Natural            (Natural)+import Test.QuickCheck            (Arbitrary (..), CoArbitrary(..), Property,+                                   property)++import Clash.Promoted.Nat         (SNat (..), snatToNum, snatToNatural)+import Clash.Promoted.Symbol      (SSymbol (..), ssymbolToString)+import Clash.XException+  (NFDataX, errorX, deepseqX, defaultSeqX, deepErrorX)++{- $setup+>>> :set -XDataKinds+>>> :set -XMagicHash+>>> :set -XTypeApplications+>>> import Clash.Promoted.Nat+>>> import Clash.XException+>>> type System = "System"+>>> let systemClockGen = clockGen @System+>>> let systemResetGen = resetGen @System+>>> import Clash.Explicit.Signal (register)+>>> let registerS = register+>>> let registerA = register+-}+++-- * Signal++-- | Determines clock edge memory elements are sensitive to. Not yet+-- implemented.+data ActiveEdge+  -- TODO: Implement in blackboxes:+  = Rising+  -- ^ Elements are sensitive to the rising edge (low-to-high) of the clock.+  | Falling+  -- ^ Elements are sensitive to the falling edge (high-to-low) of the clock.+  deriving (Show, Eq, Ord, Generic, NFData, Data, Hashable, Binary)++-- | Singleton version of 'ActiveEdge'+data SActiveEdge (edge :: ActiveEdge) where+  SRising  :: SActiveEdge 'Rising+  SFalling :: SActiveEdge 'Falling++instance Show (SActiveEdge edge) where+  show SRising = "SRising"+  show SFalling = "SFalling"++data ResetKind+  = Asynchronous+  -- ^ Elements respond /asynchronously/ to changes in their reset input. This+  -- means that they do /not/ wait for the next active clock edge, but respond+  -- immediately instead. Common on Intel FPGA platforms.+  | Synchronous+  -- ^ Elements respond /synchronously/ to changes in their reset input. This+  -- means that changes in their reset input won't take effect until the next+  -- active clock edge. Common on Xilinx FPGA platforms.+  deriving (Show, Eq, Ord, Generic, NFData, Data, Hashable)++-- | Singleton version of 'ResetKind'+data SResetKind (resetKind :: ResetKind) where+  SAsynchronous :: SResetKind 'Asynchronous+  -- See 'Asynchronous' ^++  SSynchronous  :: SResetKind 'Synchronous+  -- See 'Synchronous' ^++instance Show (SResetKind reset) where+  show SAsynchronous = "SAsynchronous"+  show SSynchronous = "SSynchronous"++-- | Determines the value for which a reset line is considered "active"+data ResetPolarity+  = ActiveHigh+  -- ^ Reset is considered active if underlying signal is 'True'.+  | ActiveLow+  -- ^ Reset is considered active if underlying signal is 'False'.+  deriving (Eq, Ord, Show, Generic, NFData, Data, Hashable)++-- | Singleton version of 'ResetPolarity'+data SResetPolarity (polarity :: ResetPolarity) where+  SActiveHigh :: SResetPolarity 'ActiveHigh+  -- See: 'ActiveHigh' ^++  SActiveLow :: SResetPolarity 'ActiveLow+  -- See: 'ActiveLow' ^++instance Show (SResetPolarity polarity) where+  show SActiveHigh = "SActiveHigh"+  show SActiveLow = "SActiveLow"++data InitBehavior+  = Unknown+  -- ^ Power up value of memory elements is /unknown/.+  | Defined+  -- ^ If applicable, power up value of a memory element is defined. Applies to+  -- 'register's for example, but not to 'blockRam'.+  deriving (Show, Eq, Ord, Generic, NFData, Data, Hashable)++data SInitBehavior (init :: InitBehavior) where+  SUnknown :: SInitBehavior 'Unknown+  -- See: 'Unknown' ^++  SDefined :: SInitBehavior 'Defined+  -- See: 'Defined' ^++instance Show (SInitBehavior init) where+  show SUnknown = "SUnknown"+  show SDefined = "SDefined"++-- | A domain with a name (@Domain@). Configures the behavior of various aspects+-- of a circuits. See the documentation of this record's field types for more+-- information on the options.+--+-- See module documentation of "Clash.Explicit.Signal" for more information on+-- how to create custom synthesis domains.+data DomainConfiguration+  = DomainConfiguration+  { _name :: Domain+  -- ^ Domain name+  , _period :: Nat+  -- ^ Period of clock in /ps/+  , _activeEdge :: ActiveEdge+  -- ^ Active edge of the clock+  , _resetKind :: ResetKind+  -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)+  , _initBehavior :: InitBehavior+  -- ^ Whether the initial (or "power up") value of memory elements is+  -- unknown/undefined, or configurable to a specific value+  , _resetPolarity :: ResetPolarity+  -- ^ Whether resets are active high or active low+  }+  deriving (Typeable)++-- | Helper type family for 'DomainPeriod'+type family DomainConfigurationPeriod (config :: DomainConfiguration) :: Nat where+  DomainConfigurationPeriod ('DomainConfiguration name period edge reset init polarity) = period++-- | Helper type family for 'DomainActiveEdge'+type family DomainConfigurationActiveEdge (config :: DomainConfiguration) :: ActiveEdge where+  DomainConfigurationActiveEdge ('DomainConfiguration name period edge reset init polarity) = edge++-- | Helper type family for 'DomainResetKind'+type family DomainConfigurationResetKind (config :: DomainConfiguration) :: ResetKind where+  DomainConfigurationResetKind ('DomainConfiguration name period edge reset init polarity) = reset++-- | Helper type family for 'DomainInitBehavior'+type family DomainConfigurationInitBehavior (config :: DomainConfiguration) :: InitBehavior where+  DomainConfigurationInitBehavior ('DomainConfiguration name period edge reset init polarity) = init++-- | Helper type family for 'DomainResetPolarity'+type family DomainConfigurationResetPolarity (config :: DomainConfiguration) :: ResetPolarity where+  DomainConfigurationResetPolarity ('DomainConfiguration name period edge reset init polarity) = polarity++-- | Convenience type to help to extract a period from a domain. Example usage:+--+-- @+-- myFunc :: (KnownDomain dom, DomainPeriod dom ~ 6000) => ...+-- @+type DomainPeriod (dom :: Domain) =+  DomainConfigurationPeriod (KnownConf dom)++-- | Convenience type to help to extract the active edge from a domain. Example+-- usage:+--+-- @+-- myFunc :: (KnownDomain dom, DomainActiveEdge dom ~ 'Rising) => ...+-- @+type DomainActiveEdge (dom :: Domain) =+  DomainConfigurationActiveEdge (KnownConf dom)++-- | Convenience type to help to extract the reset synchronicity from a+-- domain. Example usage:+--+-- @+-- myFunc :: (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous) => ...+-- @+type DomainResetKind (dom :: Domain) =+  DomainConfigurationResetKind (KnownConf dom)++-- | Convenience type to help to extract the initial value behavior from a+-- domain. Example usage:+--+-- @+-- myFunc :: (KnownDomain dom, DomainInitBehavior dom ~ 'Defined) => ...+-- @+type DomainInitBehavior (dom :: Domain) =+  DomainConfigurationInitBehavior (KnownConf dom)++-- | Convenience type to help to extract the reset polarity from a domain.+-- Example usage:+--+-- @+-- myFunc :: (KnownDomain dom, DomainResetPolarity dom ~ 'ActiveHigh) => ...+-- @+type DomainResetPolarity (dom :: Domain) =+  DomainConfigurationResetPolarity (KnownConf dom)++-- | Singleton version of 'DomainConfiguration'+data SDomainConfiguration (dom :: Domain) (conf :: DomainConfiguration) where+  SDomainConfiguration+    :: SSymbol dom+    -- Domain name ^+    -> SNat period+    -- Period of clock in /ps/ ^+    -> SActiveEdge edge+    -- Active edge of the clock (not yet+    -- implemented) ^+    -> SResetKind reset+    -- Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive) ^+    -> SInitBehavior init+    -- Whether the initial (or "power up") value of memory elements is+    -- unknown/undefined, or configurable to a specific value ^+    -> SResetPolarity polarity+    -- Whether resets are active high or active low ^+    -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)++instance Show (SDomainConfiguration dom conf) where+  show (SDomainConfiguration dom period edge reset init_ polarity) =+    unwords+      [ "SDomainConfiguration"+      , show dom+      , show period+      , show edge+      , show reset+      , show init_+      , show polarity+      ]++type KnownConfiguration dom conf = (KnownDomain dom, KnownConf dom ~ conf)++-- | A 'KnownDomain' constraint indicates that a circuit's behavior depends on+-- some properties of a domain. See 'DomainConfiguration' for more information.+class KnownSymbol dom => KnownDomain (dom :: Domain) where+  type KnownConf dom :: DomainConfiguration+  -- | Returns 'SDomainConfiguration' corresponding to an instance's 'DomainConfiguration'.+  --+  -- Example usage:+  -- > knownDomain @System+  --+  knownDomain :: SDomainConfiguration dom (KnownConf dom)++-- | Version of 'knownDomain' that takes a 'SSymbol'. For example:+--+-- >>> knownDomainByName (SSymbol @"System")+-- SDomainConfiguration System d10000 SRising SAsynchronous SDefined SActiveHigh+knownDomainByName+  :: forall dom+   . KnownDomain dom+  => SSymbol dom+  -> SDomainConfiguration dom (KnownConf dom)+knownDomainByName =+  const knownDomain+{-# INLINE knownDomainByName #-}++-- | A /clock/ (and /reset/) dom with clocks running at 100 MHz+instance KnownDomain System where+  type KnownConf System = 'DomainConfiguration System 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh++-- | System instance with defaults set for Xilinx FPGAs+instance KnownDomain XilinxSystem where+  type KnownConf XilinxSystem = 'DomainConfiguration XilinxSystem 10000 'Rising 'Synchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SSynchronous SDefined SActiveHigh++-- | System instance with defaults set for Intel FPGAs+instance KnownDomain IntelSystem where+  type KnownConf IntelSystem = 'DomainConfiguration IntelSystem 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh++-- | Convenience value to allow easy "subclassing" of System domain. Should+-- be used in combination with 'createDomain'. For example, if you just want to+-- change the period but leave all other settings in tact use:+--+-- > createDomain vSystem{vName="System10", vPeriod=10}+--+vSystem :: VDomainConfiguration+vSystem = vDomain (knownDomain @System)++-- | A clock (and reset) dom with clocks running at 100 MHz. Memory elements+-- respond to the rising edge of the clock, and asynchronously to changes in+-- reset signals. It has defined initial values, and active-high resets.+--+-- See module documentation of "Clash.Explicit.Signal" for more information on+-- how to create custom synthesis domains.+type System = ("System" :: Domain)+++-- | Convenience value to allow easy "subclassing" of IntelSystem domain. Should+-- be used in combination with 'createDomain'. For example, if you just want to+-- change the period but leave all other settings in tact use:+--+-- > createDomain vIntelSystem{vName="Intel10", vPeriod=10}+--+vIntelSystem :: VDomainConfiguration+vIntelSystem = vDomain (knownDomain @IntelSystem)++-- | A clock (and reset) dom with clocks running at 100 MHz. Memory elements+-- respond to the rising edge of the clock, and asynchronously to changes in+-- reset signals. It has defined initial values, and active-high resets.+--+-- See module documentation of "Clash.Explicit.Signal" for more information on+-- how to create custom synthesis domains.+type IntelSystem = ("IntelSystem" :: Domain)++-- | Convenience value to allow easy "subclassing" of XilinxSystem domain. Should+-- be used in combination with 'createDomain'. For example, if you just want to+-- change the period but leave all other settings in tact use:+--+-- > createDomain vXilinxSystem{vName="Xilinx10", vPeriod=10}+--+vXilinxSystem :: VDomainConfiguration+vXilinxSystem = vDomain (knownDomain @XilinxSystem)++-- | A clock (and reset) dom with clocks running at 100 MHz. Memory elements+-- respond to the rising edge of the clock, and synchronously to changes in+-- reset signals. It has defined initial values, and active-high resets.+--+-- See module documentation of "Clash.Explicit.Signal" for more information on+-- how to create custom synthesis domains.+type XilinxSystem = ("XilinxSystem" :: Domain)++-- | Same as SDomainConfiguration but allows for easy updates through record update syntax.+-- Should be used in combination with 'vDomain' and 'createDomain'. Example:+--+-- > createDomain (knownVDomain @System){vName="System10", vPeriod=10}+--+-- This duplicates the settings in the "System" domain, replaces the name and+-- period, and creates an instance for it. As most users often want to update+-- the system domain, a shortcut is available in the form:+--+-- > createDomain vSystem{vName="System10", vPeriod=10}+--+data VDomainConfiguration+  = VDomainConfiguration+  { vName :: String+  -- ^ Corresponds to '_name' on 'DomainConfiguration'+  , vPeriod :: Natural+  -- ^ Corresponds to '_period' on 'DomainConfiguration'+  , vActiveEdge :: ActiveEdge+  -- ^ Corresponds to '_edge' on 'DomainConfiguration'+  , vResetKind :: ResetKind+  -- ^ Corresponds to '_reset' on 'DomainConfiguration'+  , vInitBehavior :: InitBehavior+  -- ^ Corresponds to '_init' on 'DomainConfiguration'+  , vResetPolarity :: ResetPolarity+  -- ^ Corresponds to '_polarity' on 'DomainConfiguration'+  }++-- | Convert 'SDomainConfiguration' to 'VDomainConfiguration'. Should be used in combination with+-- 'createDomain' only.+vDomain :: SDomainConfiguration dom conf -> VDomainConfiguration+vDomain (SDomainConfiguration dom period edge reset init_ polarity) =+  VDomainConfiguration+    (ssymbolToString dom)+    (snatToNatural period)+    (case edge of {SRising -> Rising; SFalling -> Falling})+    (case reset of {SAsynchronous -> Asynchronous; SSynchronous -> Synchronous})+    (case init_ of {SDefined -> Defined; SUnknown -> Unknown})+    (case polarity of {SActiveHigh -> ActiveHigh; SActiveLow -> ActiveLow})++-- TODO: Function might reject valid type names. Figure out what's allowed.+isValidDomainName :: String -> Bool+isValidDomainName (x:xs) = isAsciiUpper x && all isAscii xs && all isAlphaNum xs+isValidDomainName _ = False++-- | Convenience method to express new domains in terms of others.+--+-- > createDomain (knownVDomain @System){vName="System10", vPeriod=10}+--+-- This duplicates the settings in the "System" domain, replaces the name and+-- period, and creates an instance for it. As most users often want to update+-- the system domain, a shortcut is available in the form:+--+-- > createDomain vSystem{vName="System10", vPeriod=10}+--+-- The function will create two extra identifiers. The first:+--+-- > type System10 = ..+--+-- You can use that as the dom to Clocks\/Resets\/Enables\/Signals. For example:+-- @Signal System10 Int@. Additionally, it will create a 'VDomainConfiguration' that you can+-- use in later calls to 'createDomain':+--+-- > vSystem10 = knownVDomain @System10+--+createDomain :: VDomainConfiguration -> Q [Dec]+createDomain (VDomainConfiguration name period edge reset init_ polarity) =+  if isValidDomainName name then do+    kdType <- [t| KnownDomain $nameT |]+    kcType <- [t| ('DomainConfiguration $nameT $periodT $edgeT $resetKindT $initT $polarityT) |]+    sDom <- [| SDomainConfiguration SSymbol SNat $edgeE $resetKindE $initE $polarityE |]++    let vNameImpl = AppE (VarE 'vDomain) (AppTypeE (VarE 'knownDomain) (LitT (StrTyLit name)))+        kdImpl = FunD 'knownDomain [Clause [] (NormalB sDom) []]+        kcImpl = mkTySynInstD ''KnownConf [LitT (StrTyLit name)] kcType+        vName' = mkName ('v':name)++    pure  [ -- KnownDomain instance (ex: instance KnownDomain "System" where ...)+            InstanceD Nothing [] kdType [kcImpl, kdImpl]++            -- Type synonym (ex: type System = "System")+          , TySynD (mkName name) [] (LitT (StrTyLit name)  `SigT`  ConT ''Domain)++            -- vDomain helper (ex: vSystem = vDomain (knownDomain @System))+          , SigD vName' (ConT ''VDomainConfiguration)+          , FunD vName' [Clause [] (NormalB vNameImpl) []]+          ]+  else+    error ("Domain names should be a valid Haskell type name, not: " ++ name)+ where++  edgeE =+    pure $+    case edge of+      Rising -> ConE 'SRising+      Falling -> ConE 'SFalling++  resetKindE =+    pure $+    case reset of+      Asynchronous -> ConE 'SAsynchronous+      Synchronous -> ConE 'SSynchronous++  initE =+    pure $+    case init_ of+      Unknown -> ConE 'SUnknown+      Defined -> ConE 'SDefined++  polarityE =+    pure $+    case polarity of+      ActiveHigh -> ConE 'SActiveHigh+      ActiveLow -> ConE 'SActiveLow++  nameT   = pure (LitT (StrTyLit name))+  periodT = pure (LitT (NumTyLit (toInteger period)))++  edgeT =+    pure $+    case edge of+      Rising -> PromotedT 'Rising+      Falling -> PromotedT 'Falling++  resetKindT =+    pure $+    case reset of+      Asynchronous -> PromotedT 'Asynchronous+      Synchronous -> PromotedT 'Synchronous++  initT =+    pure $+    case init_ of+      Unknown -> PromotedT 'Unknown+      Defined -> PromotedT 'Defined++  polarityT =+    pure $+    case polarity of+      ActiveHigh -> PromotedT 'ActiveHigh+      ActiveLow -> PromotedT 'ActiveLow+++type Domain = Symbol++infixr 5 :-+{- | Clash has synchronous 'Signal's in the form of:++@+'Signal' (dom :: 'Domain') a+@++Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,+and /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements+manipulating these 'Signal's belong.++The type-parameter, /dom/, is of the kind 'Domain' - a simple string. That+string refers to a single /synthesis domain/. A synthesis domain describes the+behavior of certain aspects of memory elements in it.++* __NB__: \"Bad things\"™  happen when you actually use a clock period of @0@,+so do __not__ do that!+* __NB__: You should be judicious using a clock with period of @1@ as you can+never create a clock that goes any faster!+* __NB__: For the best compatibility make sure your period is divisible by 2,+because some VHDL simulators don't support fractions of picoseconds.+* __NB__: Whether 'System' has good defaults depends on your target platform.+Check out 'IntelSystem' and 'XilinxSystem' too!++See the module documentation of "Clash.Signal" for more information about+domains.+-}+data Signal (dom :: Domain) a+  -- | The constructor, @(':-')@, is __not__ synthesizable.+  = a :- Signal dom a++head# :: Signal dom a -> a+head# (x' :- _ )  = x'++tail# :: Signal dom a -> Signal dom a+tail# (_  :- xs') = xs'++instance Show a => Show (Signal dom a) where+  show (x :- xs) = show x ++ " " ++ show xs++instance Lift a => Lift (Signal dom a) where+  lift ~(x :- _) = [| signal# x |]++instance Default a => Default (Signal dom a) where+  def = signal# def++instance Functor (Signal dom) where+  fmap = mapSignal#++mapSignal# :: (a -> b) -> Signal dom a -> Signal dom b+mapSignal# f (a :- as) = f a :- mapSignal# f as+{-# NOINLINE mapSignal# #-}+{-# ANN mapSignal# hasBlackBox #-}++instance Applicative (Signal dom) where+  pure  = signal#+  (<*>) = appSignal#++signal# :: a -> Signal dom a+signal# a = let s = a :- s in s+{-# NOINLINE signal# #-}+{-# ANN signal# hasBlackBox #-}++appSignal# :: Signal dom (a -> b) -> Signal dom a -> Signal dom b+appSignal# (f :- fs) xs@(~(a :- as)) = f a :- (xs `seq` appSignal# fs as) -- See [NOTE: Lazy ap]+{-# NOINLINE appSignal# #-}+{-# ANN appSignal# hasBlackBox #-}++{- NOTE: Lazy ap+Signal's ap, i.e (Applicative.<*>), must be lazy in it's second argument:++> appSignal :: Signal clk (a -> b) -> Signal clk a -> Signal clk b+> appSignal (f :- fs) ~(a :- as) = f a :- appSignal fs as++because some feedback loops, such as the loop described in 'system' in the+example at http://hackage.haskell.org/package/clash-prelude-0.10.10/docs/Clash-Prelude-BlockRam.html,+will lead to "Exception <<loop>>".++However, this "naive" lazy version is _too_ lazy and induces spaceleaks.+The current version:++> appSignal# :: Signal clk (a -> b) -> Signal clk a -> Signal clk b+> appSignal# (f :- fs) xs@(~(a :- as)) = f a :- (xs `seq` appSignal# fs as)++Is lazy enough to handle the earlier mentioned feedback loops, but doesn't leak+(as much) memory like the "naive" lazy version, because the Signal constructor+of the second argument is evaluated as soon as the tail of the result is evaluated.+-}+++-- | __WARNING: EXTREMELY EXPERIMENTAL__+--+-- The circuit semantics of this operation are unclear and/or non-existent.+-- There is a good reason there is no 'Monad' instance for 'Signal''.+--+-- Is currently treated as 'id' by the Clash compiler.+joinSignal# :: Signal dom (Signal dom a) -> Signal dom a+joinSignal# ~(xs :- xss) = head# xs :- joinSignal# (mapSignal# tail# xss)+{-# NOINLINE joinSignal# #-}+{-# ANN joinSignal# hasBlackBox #-}++instance Num a => Num (Signal dom a) where+  (+)         = liftA2 (+)+  (-)         = liftA2 (-)+  (*)         = liftA2 (*)+  negate      = fmap negate+  abs         = fmap abs+  signum      = fmap signum+  fromInteger = signal# . fromInteger++-- | __NB__: Not synthesizable+--+-- __NB__: In \"@'foldr' f z s@\":+--+-- * The function @f@ should be /lazy/ in its second argument.+-- * The @z@ element will never be used.+instance Foldable (Signal dom) where+  foldr = foldr#++-- | __NB__: Not synthesizable+--+-- __NB__: In \"@'foldr#' f z s@\":+--+-- * The function @f@ should be /lazy/ in its second argument.+-- * The @z@ element will never be used.+foldr# :: (a -> b -> b) -> b -> Signal dom a -> b+foldr# f z (a :- s) = a `f` (foldr# f z s)+{-# NOINLINE foldr# #-}+{-# ANN foldr# hasBlackBox #-}++instance Traversable (Signal dom) where+  traverse = traverse#++traverse# :: Applicative f => (a -> f b) -> Signal dom a -> f (Signal dom b)+traverse# f (a :- s) = (:-) <$> f a <*> traverse# f s+{-# NOINLINE traverse# #-}+{-# ANN traverse# hasBlackBox #-}++-- * Clocks, resets, and enables++-- | A signal of booleans, indicating whether a component is enabled. No special+-- meaning is implied, it's up to the component itself to decide how to respond+-- to its enable line. It is used throughout Clash as a global enable signal.+newtype Enable dom = Enable (Signal dom Bool)++-- | Convert 'Enable' construct to its underlying representation: a signal of+-- bools.+fromEnable :: Enable dom -> Signal dom Bool+fromEnable = coerce+{-# INLINE fromEnable #-}++-- | Convert a signal of bools to an 'Enable' construct+toEnable :: Signal dom Bool -> Enable dom+toEnable = coerce+{-# INLINE toEnable #-}++-- | Enable generator for some domain. Is simply always True.+enableGen :: Enable dom+enableGen = toEnable (pure True)++-- | A clock signal belonging to a domain named /dom/.+data Clock (dom :: Domain) = Clock (SSymbol dom)++instance Show (Clock dom) where+  show (Clock dom) = "<Clock: " ++ show dom ++ ">"++-- | Extract dom symbol from Clock+clockTag+  :: Clock dom+  -> SSymbol dom+clockTag (Clock dom) = dom++-- | Clock generator for simulations. Do __not__ use this clock generator for+-- for the /testBench/ function, use 'tbClockGen' instead.+--+-- To be used like:+--+-- @+-- clkSystem = clockGen @System+-- @+--+-- See 'DomainConfiguration' for more information on how to use synthesis domains.+clockGen+  :: KnownDomain dom+  => Clock dom+clockGen = Clock SSymbol+{-# NOINLINE clockGen #-}+{-# ANN clockGen hasBlackBox #-}++++-- | Reset generator+--+-- To be used like:+--+-- @+-- rstSystem = resetGen @System+-- @+--+-- See 'tbClockGen' for example usage.+--+resetGen+  :: forall dom+   . KnownDomain dom+  => Reset dom+resetGen = resetGenN (SNat @1)+{-# INLINE resetGen #-}++-- | Generate reset that's asserted for the first /n/ cycles.+--+-- To be used like:+--+-- @+-- rstSystem5 = resetGen @System (SNat @5)+-- @+--+-- Example usage:+--+-- >>> sampleN 7 (unsafeToHighPolarity (resetGenN @System (SNat @3)))+-- [True,True,True,False,False,False,False]+--+resetGenN+  :: forall dom n+   . (KnownDomain dom, 1 <= n)+  => SNat n+  -- ^ Number of initial cycles to hold reset high+  -> Reset dom+resetGenN n =+  let asserted = replicate (snatToNum n) True in+  unsafeFromHighPolarity (fromList (asserted ++ repeat False))+{-# ANN resetGenN hasBlackBox #-}+{-# NOINLINE resetGenN #-}+++-- | A reset signal belonging to a domain called /dom/.+--+-- The underlying representation of resets is 'Bool'.+data Reset (dom :: Domain) = Reset (Signal dom Bool)++-- | Non-ambiguous version of 'Clash.Signal.Internal.Ambiguous.resetPolarity'+resetPolarityProxy+  :: forall dom proxy polarity+   . (KnownDomain dom, DomainResetPolarity dom ~ polarity)+  => proxy dom+  -> SResetPolarity polarity+resetPolarityProxy _proxy =+  case knownDomain @dom of+    SDomainConfiguration _dom _period _edge _sync _init polarity ->+      polarity++-- | Convert a reset to an active high reset. Has no effect if reset is already+-- an active high reset. Is unsafe because it can introduce:+--+-- * <Clash-Explicit-Signal.html#metastability meta-stability>+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeToHighPolarity+  :: forall dom+   . KnownDomain dom+  => Reset dom+  -> Signal dom Bool+unsafeToHighPolarity (unsafeFromReset -> r) =+  case resetPolarityProxy (Proxy @dom) of+    SActiveHigh -> r+    SActiveLow -> not <$> r+{-# INLINE unsafeToHighPolarity #-}++-- | Convert a reset to an active low reset. Has no effect if reset is already+-- an active low reset. It is unsafe because it can introduce:+--+-- * <Clash-Explicit-Signal.html#metastability meta-stability>+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeToLowPolarity+  :: forall dom+   . KnownDomain dom+  => Reset dom+  -> Signal dom Bool+unsafeToLowPolarity (unsafeFromReset -> r) =+  case resetPolarityProxy (Proxy @dom) of+    SActiveHigh -> not <$> r+    SActiveLow -> r+{-# INLINE unsafeToLowPolarity #-}++-- | 'unsafeFromReset' is unsafe because it can introduce:+--+-- * <Clash-Explicit-Signal.html#metastability meta-stability>+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+--+-- __NB__: You probably want to use 'unsafeToLowPolarity' or+-- 'unsafeToHighPolarity'.+unsafeFromReset+  :: Reset dom+  -> Signal dom Bool+unsafeFromReset (Reset r) = r+{-# NOINLINE unsafeFromReset #-}+{-# ANN unsafeFromReset hasBlackBox #-}++-- | 'unsafeToReset' is unsafe. For asynchronous resets it is unsafe+-- because it can introduce combinatorial loops. In case of synchronous resets+-- it can lead to <Clash-Explicit-Signal.html#metastability meta-stability>+-- issues in the presence of asynchronous resets.+--+-- __NB__: You probably want to use 'unsafeFromLowPolarity' or+-- 'unsafeFromHighPolarity'.+unsafeToReset+  :: Signal dom Bool+  -> Reset dom+unsafeToReset r = Reset r+{-# NOINLINE unsafeToReset #-}+{-# ANN unsafeToReset hasBlackBox #-}++-- | Interpret a signal of bools as an active high reset and convert it to+-- a reset signal corresponding to the domain's setting.+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeFromHighPolarity+  :: forall dom+   . KnownDomain dom+  => Signal dom Bool+  -- ^ Reset signal that's 'True' when active, and 'False' when inactive.+  -> Reset dom+unsafeFromHighPolarity r =+  unsafeToReset $+    case resetPolarityProxy (Proxy @dom) of+      SActiveHigh -> r+      SActiveLow -> not <$> r++-- | Interpret a signal of bools as an active low reset and convert it to+-- a reset signal corresponding to the domain's setting.+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeFromLowPolarity+  :: forall dom+   . KnownDomain dom+  => Signal dom Bool+  -- ^ Reset signal that's 'False' when active, and 'True' when inactive.+  -> Reset dom+unsafeFromLowPolarity r =+  unsafeToReset $+    case resetPolarityProxy (Proxy @dom) of+      SActiveHigh -> not <$> r+      SActiveLow -> r++-- | Invert reset signal+invertReset :: Reset dom -> Reset dom+invertReset = unsafeToReset . fmap not . unsafeFromReset++infixr 2 .||.+-- | The above type is a generalization for:+--+-- @+-- __(.||.)__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('||') that returns a 'Clash.Signal.Signal' of 'Bool'+(.||.) :: Applicative f => f Bool -> f Bool -> f Bool+(.||.) = liftA2 (||)++infixr 3 .&&.+-- | The above type is a generalization for:+--+-- @+-- __(.&&.)__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('&&') that returns a 'Clash.Signal.Signal' of 'Bool'+(.&&.) :: Applicative f => f Bool -> f Bool -> f Bool+(.&&.) = liftA2 (&&)++-- [Note: register strictness annotations]+--+-- In order to produce the first (current) value of the register's output+-- signal, 'o', we don't need to know the shape of either input (enable or+-- value-in).  This is important, because both values might be produced from+-- the output in a feedback loop, so we can't know their shape (pattern+-- match) them until we have produced output.+--+-- Thus, we use lazy pattern matching to delay inspecting the shape of+-- either argument until output has been produced.+--+-- However, both arguments need to be evaluated to WHNF as soon as possible+-- to avoid a space-leak.  Below, we explicitly reduce the value-in signal+-- using 'seq' as the tail of our output signal is produced.  On the other+-- hand, because the value of the tail depends on the value of the enable+-- signal 'e', it will be forced by the 'if'/'then' statement and we don't+-- need to 'seq' it explicitly.++delay#+  :: forall dom a+   . ( KnownDomain dom+     , NFDataX a )+  => Clock dom+  -> Enable dom+  -> a+  -> Signal dom a+  -> Signal dom a+delay# (Clock dom) (fromEnable -> en) powerUpVal0 =+    go powerUpVal1 en+  where+    powerUpVal1 :: a+    powerUpVal1 =+      case knownDomainByName dom of+        SDomainConfiguration _dom _period _edge _sync SDefined _polarity ->+          powerUpVal0+        SDomainConfiguration _dom _period _edge _sync SUnknown _polarity ->+          deepErrorX ("First value of `delay` unknown on domain " ++ show dom)++    go o (e :- es) as@(~(x :- xs)) =+      let o' = if e then x else o+      -- See [Note: register strictness annotations]+      in  o `defaultSeqX` o :- (as `seq` go o' es xs)+{-# NOINLINE delay# #-}+{-# ANN delay# hasBlackBox #-}++-- | A register with a power up and reset value. Power up values are not+-- supported on all platforms, please consult the manual of your target platform+-- and check the notes below.+--+-- Xilinx: power up values and reset values MUST be the same. If they are not,+-- the Xilinx tooling __will ignore the reset value__ and use the power up value+-- instead. Source: MIA+--+-- Intel: power up values and reset values MUST be the same. If they are not,+-- the Intel tooling __will ignore the power up value__ and use the reset value+-- instead. Source: https://www.intel.com/content/www/us/en/programmable/support/support-resources/knowledge-base/solutions/rd01072011_91.html+register#+  :: forall dom  a+   . ( KnownDomain dom+     , NFDataX a )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> a+  -- ^ Power up value+  -> a+  -- ^ Reset value+  -> Signal dom a+  -> Signal dom a+register# (Clock dom) rst (fromEnable -> ena) powerUpVal0 resetVal =+  case knownDomainByName dom of+    SDomainConfiguration _name _period _edge SSynchronous _init _polarity ->+      goSync powerUpVal1 (unsafeToHighPolarity rst) ena+    SDomainConfiguration _name _period _edge SAsynchronous _init _polarity ->+      goAsync powerUpVal1 (unsafeToHighPolarity rst) ena+ where+  powerUpVal1 :: a+  powerUpVal1 =+    case knownDomainByName dom of+      SDomainConfiguration _dom _period _edge _sync SDefined _polarity ->+        powerUpVal0+      SDomainConfiguration _dom _period _edge _sync SUnknown _polarity ->+        deepErrorX ("First value of register undefined on domain " ++ show dom)++  goSync+    :: a+    -> Signal dom Bool+    -> Signal dom Bool+    -> Signal dom a+    -> Signal dom a+  goSync o rt@(~(r :- rs)) enas@(~(e :- es)) as@(~(x :- xs)) =+    let oE = if e then x else o+        oR = if r then resetVal else oE+        -- [Note: register strictness annotations]+    in  o `defaultSeqX` o :- (rt `seq` enas `seq` as `seq` goSync oR rs es xs)++  goAsync+    :: a+    -> Signal dom Bool+    -> Signal dom Bool+    -> Signal dom a+    -> Signal dom a+  goAsync o (r :- rs) enas@(~(e :- es)) as@(~(x :- xs)) =+    let oR = if r then resetVal else o+        oE = if r then resetVal else (if e then x else o)+        -- [Note: register strictness annotations]+    in  oR `defaultSeqX` oR :- (as `seq` enas `seq` goAsync oE rs es xs)+{-# NOINLINE register# #-}+{-# ANN register# hasBlackBox #-}++-- | The above type is a generalization for:+--+-- @+-- __mux__ :: 'Clash.Signal.Signal' 'Bool' -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a+-- @+--+-- A multiplexer. Given "@'mux' b t f@", output @t@ when @b@ is 'True', and @f@+-- when @b@ is 'False'.+mux :: Applicative f => f Bool -> f a -> f a -> f a+mux = liftA3 (\b t f -> if b then t else f)+{-# INLINE mux #-}++infix 4 .==.+-- | The above type is a generalization for:+--+-- @+-- __(.==.)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('==') that returns a 'Clash.Signal.Signal' of 'Bool'+(.==.) :: (Eq a, Applicative f) => f a -> f a -> f Bool+(.==.) = liftA2 (==)++infix 4 ./=.+-- | The above type is a generalization for:+--+-- @+-- __(./=.)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('/=') that returns a 'Clash.Signal.Signal' of 'Bool'+(./=.) :: (Eq a, Applicative f) => f a -> f a -> f Bool+(./=.) = liftA2 (/=)++infix 4 .<.+-- | The above type is a generalization for:+--+-- @+-- __(.<.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('<') that returns a 'Clash.Signal.Signal' of 'Bool'+(.<.) :: (Ord a, Applicative f) => f a -> f a -> f Bool+(.<.) = liftA2 (<)++infix 4 .<=.+-- | The above type is a generalization for:+--+-- @+-- __(.<=.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('<=') that returns a 'Clash.Signal.Signal' of 'Bool'+(.<=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool+(.<=.) = liftA2 (<=)++infix 4 .>.+-- | The above type is a generalization for:+--+-- @+-- __(.>.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+-- It is a version of ('>') that returns a 'Clash.Signal.Signal' of 'Bool'+(.>.) :: (Ord a, Applicative f) => f a -> f a -> f Bool+(.>.) = liftA2 (>)++infix 4 .>=.+-- | The above type is a generalization for:+--+-- @+-- __(.>=.)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'+-- @+--+--  It is a version of ('>=') that returns a 'Clash.Signal.Signal' of 'Bool'+(.>=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool+(.>=.) = liftA2 (>=)++instance Fractional a => Fractional (Signal dom a) where+  (/)          = liftA2 (/)+  recip        = fmap recip+  fromRational = signal# . fromRational++instance Arbitrary a => Arbitrary (Signal dom a) where+  arbitrary = liftA2 (:-) arbitrary arbitrary++instance CoArbitrary a => CoArbitrary (Signal dom a) where+  coarbitrary xs gen = do+    n <- arbitrary+    coarbitrary (take (abs n) (sample_lazy xs)) gen++-- | The above type is a generalization for:+--+-- @+-- __testFor__ :: 'Int' -> 'Clash.Signal.Signal' Bool -> 'Property'+-- @+--+-- @testFor n s@ tests the signal @s@ for @n@ cycles.+--+-- __NB__: This function is not synthesizable+testFor :: Foldable f => Int -> f Bool -> Property+testFor n = property . and . take n . sample++-- * List \<-\> Signal conversion (not synthesizable)++-- | The above type is a generalization for:+--+-- @+-- __sample__ :: 'Clash.Signal.Signal' a -> [a]+-- @+--+-- Get an infinite list of samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Clash.Signal.Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- __NB__: This function is not synthesizable+sample :: (Foldable f, NFDataX a) => f a -> [a]+sample = foldr (\a b -> deepseqX a (a : b)) []++-- | The above type is a generalization for:+--+-- @+-- __sampleN__ :: Int -> 'Clash.Signal.Signal' a -> [a]+-- @+--+-- Get a list of @n@ samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Clash.Signal.Signal'+-- at consecutive clock cycles+--+-- > sampleN 3 s == [s0, s1, s2]+--+-- __NB__: This function is not synthesizable+sampleN :: (Foldable f, NFDataX a) => Int -> f a -> [a]+sampleN n = take n . sample++-- | Create a 'Clash.Signal.Signal' from a list+--+-- Every element in the list will correspond to a value of the signal for one+-- clock cycle.+--+-- >>> sampleN 2 (fromList [1,2,3,4,5])+-- [1,2]+--+-- __NB__: This function is not synthesizable+fromList :: NFDataX a => [a] -> Signal dom a+fromList = Prelude.foldr (\a b -> deepseqX a (a :- b)) (errorX "finite list")++-- * Simulation functions (not synthesizable)++-- | Simulate a (@'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' b@) function+-- given a list of samples of type @a@+--+-- >>> simulate (register systemClockGen resetGen enableGen 8) [1, 1, 2, 3]+-- [8,8,1,2,3...+-- ...+--+-- __NB__: This function is not synthesizable+simulate :: (NFDataX a, NFDataX b) => (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]+simulate f = sample . f . fromList++-- | The above type is a generalization for:+--+-- @+-- __sample__ :: 'Clash.Signal.Signal' a -> [a]+-- @+--+-- Get an infinite list of samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Clash.Signal.Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- __NB__: This function is not synthesizable+sample_lazy :: Foldable f => f a -> [a]+sample_lazy = foldr (:) []++-- | The above type is a generalization for:+--+-- @+-- __sampleN__ :: Int -> 'Clash.Signal.Signal' a -> [a]+-- @+--+-- Get a list of @n@ samples from a 'Clash.Signal.Signal'+--+-- The elements in the list correspond to the values of the 'Clash.Signal.Signal'+-- at consecutive clock cycles+--+-- > sampleN 3 s == [s0, s1, s2]+--+-- __NB__: This function is not synthesizable+sampleN_lazy :: Foldable f => Int -> f a -> [a]+sampleN_lazy n = take n . sample_lazy++-- | Create a 'Clash.Signal.Signal' from a list+--+-- Every element in the list will correspond to a value of the signal for one+-- clock cycle.+--+-- >>> sampleN 2 (fromList [1,2,3,4,5] :: Signal System Int)+-- [1,2]+--+-- __NB__: This function is not synthesizable+fromList_lazy :: [a] -> Signal dom a+fromList_lazy = Prelude.foldr (:-) (error "finite list")++-- * Simulation functions (not synthesizable)++-- | Simulate a (@'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' b@) function+-- given a list of samples of type @a@+--+-- >>> simulate (register systemClockGen resetGen enableGen 8) [1, 1, 2, 3]+-- [8,8,1,2,3...+-- ...+--+-- __NB__: This function is not synthesizable+simulate_lazy :: (Signal dom1 a -> Signal dom2 b) -> [a] -> [b]+simulate_lazy f = sample_lazy . f . fromList_lazy++-- | Calculate the period, in __ps__, given a frequency in __Hz__+--+-- i.e. to calculate the clock period for a circuit to run at 240 MHz we get+--+-- >>> hzToPeriod 240e6+-- 4167+--+-- __NB__: This function is /not/ synthesizable+-- __NB__: This function is lossy. I.e., hzToPeriod . periodToHz /= id.+hzToPeriod :: HasCallStack => Double -> Natural+hzToPeriod freq | freq <= 0.0 = error "Frequency must be strictly positive"+                | otherwise   = ceiling ((1.0 / freq) / 1.0e-12)++-- | Calculate the frequence in __Hz__, given the period in __ps__+--+-- i.e. to calculate the clock frequency of a clock with a period of 5000 ps:+--+-- >>> periodToHz 5000+-- 2.0e8+--+-- __NB__: This function is /not/ synthesizable+-- __NB__: This function is lossy. I.e., hzToPeriod . periodToHz /= id.+periodToHz :: Natural -> Double+periodToHz period = 1.0 / (1.0e-12 * fromIntegral period)
+ src/Clash/Signal/Internal/Ambiguous.hs view
@@ -0,0 +1,118 @@+{-# LANGUAGE AllowAmbiguousTypes    #-}+{-# LANGUAGE RankNTypes             #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE TypeApplications       #-}+{-# LANGUAGE TypeFamilies           #-}++module Clash.Signal.Internal.Ambiguous+  ( knownVDomain+  , clockPeriod+  , activeEdge+  , resetKind+  , initBehavior+  , resetPolarity+  ) where++import           Clash.Signal.Internal+import           Clash.Promoted.Nat         (SNat)++-- | Get the clock period from a KnownDomain context+clockPeriod+  :: forall dom period+   . (KnownDomain dom, DomainPeriod dom ~ period)+  => SNat period+clockPeriod =+  case knownDomain @dom of+    SDomainConfiguration _dom period _edge _sync _init _polarity ->+      period+{-# NOINLINE clockPeriod #-}+-- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662++-- | Get 'ActiveEdge' from a KnownDomain context. Example usage:+--+-- @+-- f :: forall dom . KnownDomain dom => ....+-- f a b c =+--   case activeEdge @dom of+--     SRising -> foo+--     SFalling -> bar+-- @+activeEdge+  :: forall dom edge+   . (KnownDomain dom, DomainActiveEdge dom ~ edge)+  => SActiveEdge edge+activeEdge =+  case knownDomain @dom of+    SDomainConfiguration _dom _period edge _sync _init _polarity ->+      edge+{-# NOINLINE activeEdge #-}+-- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662++-- | Get 'ResetKind' from a KnownDomain context. Example usage:+--+-- @+-- f :: forall dom . KnownDomain dom => ....+-- f a b c =+--   case resetKind @dom of+--     SAsynchronous -> foo+--     SSynchronous -> bar+-- @+resetKind+  :: forall dom sync+   . (KnownDomain dom, DomainResetKind dom ~ sync)+  => SResetKind sync+resetKind =+  case knownDomain @dom of+    SDomainConfiguration _dom _period _edge sync _init _polarity ->+      sync+{-# NOINLINE resetKind #-}+-- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662++-- | Get 'InitBehavior' from a KnownDomain context. Example usage:+--+-- @+-- f :: forall dom . KnownDomain dom => ....+-- f a b c =+--   case initBehavior @dom of+--     SDefined -> foo+--     SUnknown -> bar+-- @+initBehavior+  :: forall dom init+   . (KnownDomain dom, DomainInitBehavior dom ~ init)+  => SInitBehavior init+initBehavior =+  case knownDomain @dom of+    SDomainConfiguration _dom _period _edge _sync init_ _polarity ->+      init_+{-# NOINLINE initBehavior #-}+-- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662++-- | Get 'ResetPolarity' from a KnownDomain context. Example usage:+--+-- @+-- f :: forall dom . KnownDomain dom => ....+-- f a b c =+--   case resetPolarity @dom of+--     SActiveHigh -> foo+--     SActiveLow -> bar+-- @+resetPolarity+  :: forall dom polarity+   . (KnownDomain dom, DomainResetPolarity dom ~ polarity)+  => SResetPolarity polarity+resetPolarity =+  case knownDomain @dom of+    SDomainConfiguration _dom _period _edge _sync _init polarity ->+      polarity+{-# NOINLINE resetPolarity #-}+-- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662++-- | Like 'knownDomain but yields a 'VDomainConfiguration'. Should only be used+-- in combination with 'createDomain'.+knownVDomain+  :: forall dom+   . KnownDomain dom+  => VDomainConfiguration+knownVDomain =+  vDomain (knownDomain @dom)
+ src/Clash/Signal/Trace.hs view
@@ -0,0 +1,585 @@+{-|+Copyright  :  (C) 2018, Google Inc.+                  2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>++Utilities for tracing signals and dumping them in various ways. Example usage:++@+import Clash.Prelude hiding (writeFile)+import Data.Text.IO  (writeFile)++-- | Count and wrap around+subCounter :: SystemClockResetEnable => Signal System (Index 3)+subCounter = traceSignal1 "sub" counter+  where+    counter =+      register 0 (fmap succ' counter)++    succ' c+      | c == maxBound = 0+      | otherwise     = c + 1++-- | Count, but only when my subcounter is wrapping around+mainCounter :: SystemClockResetEnable => Signal System (Signed 64)+mainCounter = traceSignal1 "main" counter+  where+    counter =+      register 0 (fmap succ' $ bundle (subcounter,counter))++    succ' (sc, c)+      | sc == maxBound = c + 1+      | otherwise      = c++-- | Collect traces, and dump them to a VCD file.+main :: SystemClockResetEnable => IO ()+main = do+  let cntrOut = exposeClockResetEnable mainCounter systemClockGen systemResetGen+  vcd <- dumpVCD (0, 100) cntrOut ["main", "sub"]+  case vcd of+    Left msg ->+      error msg+    Right contents ->+      writeFile "mainCounter.vcd" contents+@+-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE BangPatterns        #-}+{-# LANGUAGE DataKinds           #-}+{-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE MagicHash           #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE TypeFamilies        #-}+{-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE ViewPatterns        #-}++{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise       #-}++module Clash.Signal.Trace+  (+  -- * Tracing functions+  -- ** Simple+    traceSignal1+  , traceVecSignal1+  -- ** Tracing in a multi-clock environment+  , traceSignal+  , traceVecSignal++  -- * VCD dump functions+  , dumpVCD++  -- * Replay functions+  , dumpReplayable+  , replay++  -- * Internal+  -- ** Types+  , Period+  , Changed+  , Value+  , Width+  , TraceMap+  -- ** Functions+  , traceSignal#+  , traceVecSignal#+  , dumpVCD#+  , dumpVCD##+  , waitForTraces#+  , traceMap#+  ) where++-- Clash:+import           Clash.Signal.Internal (fromList)+import           Clash.Signal+  (KnownDomain(..), SDomainConfiguration(..), Signal, bundle, unbundle)+import           Clash.Sized.Vector    (Vec, iterateI)+import qualified Clash.Sized.Vector    as Vector+import           Clash.Class.BitPack   (BitPack, BitSize, pack, unpack)+import           Clash.Promoted.Nat    (snatToNum, SNat(..))+import           Clash.Signal.Internal (sample)+import           Clash.XException      (deepseqX, NFDataX)+import           Clash.Sized.Internal.BitVector+  (BitVector(BV))++-- Haskell / GHC:+import           Control.Monad         (foldM)+import           Data.Bits             (testBit)+import           Data.Binary           (encode, decodeOrFail)+import           Data.ByteString.Lazy  (ByteString)+import qualified Data.ByteString.Lazy  as ByteStringLazy+import           Data.Char             (ord, chr)+import           Data.IORef+  (IORef, atomicModifyIORef', atomicWriteIORef, newIORef, readIORef)+import           Data.List             (foldl1', foldl', unzip4, transpose)+import qualified Data.Map.Strict       as Map+import           Data.Maybe            (fromMaybe, catMaybes)+import qualified Data.Text             as Text+import           Data.Time.Clock       (UTCTime, getCurrentTime)+import           Data.Time.Format      (formatTime, defaultTimeLocale)+import           GHC.Stack             (HasCallStack)+import           GHC.TypeLits          (KnownNat, type (+))+import           System.IO.Unsafe      (unsafePerformIO)+import           Type.Reflection       (Typeable, TypeRep, typeRep)++#ifdef CABAL+import qualified Data.Version+import qualified Paths_clash_prelude+#endif++type Period   = Int+type Changed  = Bool+type Value    = (Integer, Integer) -- (Mask, Value)+type Width    = Int++-- | Serialized TypeRep we need to store for dumpReplayable / replay+type TypeRepBS = ByteString++type TraceMap  = Map.Map String (TypeRepBS, Period, Width, [Value])++-- | Map of traces used by the non-internal trace and dumpvcd functions.+traceMap# :: IORef TraceMap+traceMap# = unsafePerformIO (newIORef Map.empty)+{-# NOINLINE traceMap# #-}++mkTrace+  :: HasCallStack+  => KnownNat (BitSize a)+  => BitPack a+  => NFDataX a+  => Signal dom a+  -> [Value]+mkTrace signal = sample (unsafeToTup . pack <$> signal)+ where+  unsafeToTup (BV mask value) = (mask, value)++-- | Trace a single signal. Will emit an error if a signal with the same name+-- was previously registered.+traceSignal#+  :: forall dom a+   . ( KnownNat (BitSize a)+     , BitPack a+     , NFDataX a+     , Typeable a )+  => IORef TraceMap+  -- ^ Map to store the trace+  -> Int+  -- ^ The associated clock period for the trace+  -> String+  -- ^ Name of signal in the VCD output+  -> Signal dom a+  -- ^ Signal to trace+  -> IO (Signal dom a)+traceSignal# traceMap period traceName signal =+  atomicModifyIORef' traceMap $ \m ->+    if Map.member traceName m then+      error $ "Already tracing a signal with the name: '" ++ traceName ++ "'."+    else+      ( Map.insert+          traceName+          ( encode (typeRep @a)+          , period+          , width+          , mkTrace signal)+          m+      , signal)+ where+  width = snatToNum (SNat @ (BitSize a))+{-# NOINLINE traceSignal# #-}++-- | Trace a single vector signal: each element in the vector will show up as+-- a different trace. If the trace name already exists, this function will emit+-- an error.+traceVecSignal#+  :: forall dom n a+   . ( KnownNat (BitSize a)+     , KnownNat n+     , BitPack a+     , NFDataX a+     , Typeable a )+  => IORef TraceMap+  -- ^ Map to store the traces+  -> Int+  -- ^ Associated clock period for the trace+  -> String+  -- ^ Name of signal in the VCD output. Will be appended by _0, _1, ..., _n.+  -> Signal dom (Vec (n+1) a)+  -- ^ Signal to trace+  -> IO (Signal dom (Vec (n+1) a))+traceVecSignal# traceMap period vecTraceName (unbundle -> vecSignal) =+  fmap bundle . sequenceA $+    Vector.zipWith trace' (iterateI succ (0 :: Int)) vecSignal+ where+  trace' i s = traceSignal# traceMap period (name' i) s+  name' i    = vecTraceName ++ "_" ++ show i+{-# NOINLINE traceVecSignal# #-}++-- | Trace a single signal. Will emit an error if a signal with the same name+-- was previously registered.+--+-- __NB__ Works correctly when creating VCD files from traced signal in+-- multi-clock circuits. However 'traceSignal1' might be more convenient to+-- use when the domain of your circuit is polymorphic.+traceSignal+  :: forall dom  a+   . ( KnownDomain dom+     , KnownNat (BitSize a)+     , BitPack a+     , NFDataX a+     , Typeable a )+  => String+  -- ^ Name of signal in the VCD output+  -> Signal dom a+  -- ^ Signal to trace+  -> Signal dom a+traceSignal traceName signal =+  case knownDomain @dom of+    SDomainConfiguration _dom period _edge _reset _init _polarity ->+      unsafePerformIO $+        traceSignal# traceMap# (snatToNum period) traceName signal+{-# NOINLINE traceSignal #-}++-- | Trace a single signal. Will emit an error if a signal with the same name+-- was previously registered.+--+-- __NB__ associates the traced signal with a clock period of /1/, which+-- results in incorrect VCD files when working with circuits that have+-- multiple clocks. Use 'traceSignal' when working with circuits that have+-- multiple clocks.+traceSignal1+  :: ( KnownNat (BitSize a)+     , BitPack a+     , NFDataX a+     , Typeable a )+  => String+  -- ^ Name of signal in the VCD output+  -> Signal dom a+  -- ^ Signal to trace+  -> Signal dom a+traceSignal1 traceName signal =+  unsafePerformIO (traceSignal# traceMap# 1 traceName signal)+{-# NOINLINE traceSignal1 #-}++-- | Trace a single vector signal: each element in the vector will show up as+-- a different trace. If the trace name already exists, this function will emit+-- an error.+--+-- __NB__ Works correctly when creating VCD files from traced signal in+-- multi-clock circuits. However 'traceSignal1' might be more convinient to+-- use when the domain of your circuit is polymorphic.+traceVecSignal+  :: forall dom a  n+   . ( KnownDomain dom+     , KnownNat (BitSize a)+     , KnownNat n+     , BitPack a+     , NFDataX a+     , Typeable a )+  => String+  -- ^ Name of signal in debugging output. Will be appended by _0, _1, ..., _n.+  -> Signal dom (Vec (n+1) a)+  -- ^ Signal to trace+  -> Signal dom (Vec (n+1) a)+traceVecSignal traceName signal =+  case knownDomain @dom of+    SDomainConfiguration _dom period _edge _reset _init _polarity ->+      unsafePerformIO $+        traceVecSignal# traceMap# (snatToNum period) traceName signal+{-# NOINLINE traceVecSignal #-}++-- | Trace a single vector signal: each element in the vector will show up as+-- a different trace. If the trace name already exists, this function will emit+-- an error.+--+-- __NB__ associates the traced signal with a clock period of /1/, which+-- results in incorrect VCD files when working with circuits that have+-- multiple clocks. Use 'traceSignal' when working with circuits that have+-- multiple clocks.+traceVecSignal1+  :: ( KnownNat (BitSize a)+     , KnownNat n+     , BitPack a+     , NFDataX a+     , Typeable a )+  => String+  -- ^ Name of signal in debugging output. Will be appended by _0, _1, ..., _n.+  -> Signal dom (Vec (n+1) a)+  -- ^ Signal to trace+  -> Signal dom (Vec (n+1) a)+traceVecSignal1 traceName signal =+  unsafePerformIO $ traceVecSignal# traceMap# 1 traceName signal+{-# NOINLINE traceVecSignal1 #-}++iso8601Format :: UTCTime -> String+iso8601Format = formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S"++toPeriodMap :: TraceMap -> Map.Map Period [(String, Width, [Value])]+toPeriodMap m = foldl' go Map.empty (Map.assocs m)+  where+    go periodMap (traceName, (_rep, period, width, values)) =+      Map.alter (Just . go') period periodMap+        where+          go' = ((traceName, width, values):) . (fromMaybe [])++flattenMap :: Map.Map a [b] -> [(a, b)]+flattenMap m = concat [[(a, b) | b <- bs] | (a, bs) <- Map.assocs m]++printable :: Char -> Bool+printable (ord -> c) = 33 <= c && c <= 126++-- | Same as @dumpVCD@, but supplied with a custom tracemap and a custom timestamp+dumpVCD##+  :: (Int, Int)+  -- ^ (offset, number of samples)+  -> TraceMap+  -> UTCTime+  -> Either String Text.Text+dumpVCD## (offset, cycles) traceMap now+  | offset < 0 =+      error $ "dumpVCD: offset was " ++ show offset ++ ", but cannot be negative."+  | cycles < 0 =+      error $ "dumpVCD: cycles was " ++ show cycles ++ ", but cannot be negative."+  | null traceMap =+      error $ "dumpVCD: no traces found. Extend the given trace names."+  | Map.size traceMap > 126 - 33 =+      Left $ "Tracemap contains more than 93 traces, which is not supported by VCD."+  | not $ null $ offensiveNames =+      Left $ unwords [ "Trace '" ++ head offensiveNames ++ "' contains"+                     , "non-printable ASCII characters, which is not"+                     , "supported by VCD." ]+  | otherwise =+      Right $ Text.unlines [ Text.unwords headerDate+                           , Text.unwords headerVersion+                           , Text.unwords headerComment+                           , Text.pack $ unwords headerTimescale+                           , "$scope module logic $end"+                           , Text.intercalate "\n" headerWires+                           , "$upscope $end"+                           , "$enddefinitions $end"+                           , "#0"+                           , "$dumpvars"+                           , Text.intercalate "\n" initValues+                           , "$end"+                           , Text.intercalate "\n" $ catMaybes bodyParts+                           ]+ where+  offensiveNames = filter (any (not . printable)) traceNames++  labels = map chr [33..126]++  timescale = foldl1' gcd (Map.keys periodMap)+  periodMap = toPeriodMap traceMap++  -- Normalize traces until they have the "same" period. That is, assume+  -- we have two traces; trace A with a period of 20 ps and trace B with+  -- a period of 40 ps:+  --+  --   A: [A1, A2, A3, ...]+  --   B: [B1, B2, B3, ...]+  --+  -- After normalization these look like:+  --+  --   A: [A1, A2, A3, A4, A5, A6, ...]+  --   B: [B1, B1, B2, B2, B3, B3, ...]+  --+  -- ..because B is "twice as slow" as A.+  (periods, traceNames, widths, valuess) =+    unzip4 $ map+      (\(a, (b, c, d)) -> (a, b, c, d))+      (flattenMap periodMap)++  periods' = map (`quot` timescale) periods+  valuess' = map slice $ zipWith normalize periods' valuess+  normalize period values = concatMap (replicate period) values+  slice values = drop offset $ take cycles values++  headerDate       = ["$date", Text.pack $ iso8601Format now, "$end"]++#ifdef CABAL+  clashVer         = Data.Version.showVersion Paths_clash_prelude.version+#else+  clashVer         = "development"+#endif+  headerVersion    = ["$version", "Generated by Clash", Text.pack clashVer , "$end"]+  headerComment    = ["$comment", "No comment", "$end"]+  headerTimescale  = ["$timescale", (show timescale) ++ "ps", "$end"]+  headerWires      = [ Text.unwords $ headerWire w l n+                     | (w, l, n) <- (zip3 widths labels traceNames)]+  headerWire w l n = map Text.pack ["$var wire", show w, [l], n, "$end"]+  initValues       = map Text.pack $ zipWith ($) formatters inits++  -- Guard against (partially) undefined bitvectors:+  toIntegers :: Int -> [[Value]] -> [[Integer]]+  toIntegers _ [] = []+  toIntegers !cyclen (xs:xss) =+    zipWith vToInteger traceNames xs : toIntegers (cyclen + 1) xss+   where+    vToInteger _traceName (0, v) = v+    vToInteger traceName (mask, v) =+      error $ "dumpVCD can't handle (partially) undefined values yet, but "+           ++ "encountered one at cycle " ++ show cyclen ++ " of traced signal "+           ++ "labeled " ++ show traceName ++ ". Mask was " ++ show mask+           ++ ", value was " ++ show v ++ "."++  formatters = zipWith format widths labels+  inits = map head (toIntegers 0 valuess')+  tails = map changed (toIntegers 0 valuess')++  -- | Format single value according to VCD spec+  format :: Width -> Char -> Integer -> String+  format 1 label 0   = ['0', label, '\n']+  format 1 label 1   = ['1', label, '\n']+  format 1 label val =+    error $ "Width of " ++ show label ++ " was " ++ show val+  format n label val =+    let b2b b = if b then '1' else '0' in+    "b" ++ map (b2b . testBit val) (reverse [0..n-1]) ++ " " ++ [label]++  -- | Given a list of values, return a list of list of bools indicating+  -- if a value changed. The first value is *not* included in the result.+  changed :: [Integer] -> [(Changed, Integer)]+  changed (s:ss) = zip (zipWith (/=) (s:ss) ss) ss+  changed []     = []++  bodyParts :: [Maybe Text.Text]+  bodyParts = zipWith go [0..] (map bodyPart (Data.List.transpose tails))+    where+      go :: Int -> Maybe Text.Text -> Maybe Text.Text+      go (Text.pack . show -> n) t =+        let pre = Text.concat ["#", n, "\n"] in+        fmap (Text.append pre) t++  bodyPart :: [(Changed, Integer)] -> Maybe Text.Text+  bodyPart values =+    let formatted  = [(c, f v) | (f, (c,v)) <- zip formatters values]+        formatted' = map (Text.pack . snd) $ filter fst $ formatted in+    if null formatted' then Nothing else Just $ Text.intercalate "\n" formatted'++-- | Same as @dumpVCD@, but supplied with a custom tracemap+dumpVCD#+  :: NFDataX a+  => IORef TraceMap+  -- ^ Map with collected traces+  -> (Int, Int)+  -- ^ (offset, number of samples)+  -> Signal dom a+  -- ^ (One of) the output(s) the circuit containing the traces+  -> [String]+  -- ^ The names of the traces you definitely want to be dumped to the VCD file+  -> IO (Either String Text.Text)+dumpVCD# traceMap slice signal traceNames = do+  waitForTraces# traceMap signal traceNames+  m <- readIORef traceMap+  fmap (dumpVCD## slice m) getCurrentTime++-- | Produce a four-state VCD (Value Change Dump) according to IEEE+-- 1364-{1995,2001}. This function fails if a trace name contains either+-- non-printable or non-VCD characters.+--+-- Due to lazy evaluation, the created VCD files might not contain all the+-- traces you were expecting. You therefore have to provide a list of names+-- you definately want to be dumped in the VCD file.+--+-- For example:+--+-- @+-- vcd <- dumpVCD (0, 100) cntrOut ["main", "sub"]+-- @+--+-- Evaluates /cntrOut/ long enough in order for to guarantee that the @main@,+-- and @sub@ traces end up in the generated VCD file.+dumpVCD+  :: NFDataX a+  => (Int, Int)+  -- ^ (offset, number of samples)+  -> Signal dom a+  -- ^ (One of) the outputs of the circuit containing the traces+  -> [String]+  -- ^ The names of the traces you definitely want to be dumped in the VCD file+  -> IO (Either String Text.Text)+dumpVCD = dumpVCD# traceMap#++-- | Dump a number of samples to a replayable bytestring.+dumpReplayable+  :: forall a dom+   . NFDataX a+  => Int+  -- ^ Number of samples+  -> Signal dom a+  -- ^ (One of) the outputs of the circuit containing the traces+  -> String+  -- ^ Name of trace to dump+  -> IO ByteString+dumpReplayable n oSignal traceName = do+  waitForTraces# traceMap# oSignal [traceName]+  replaySignal <- (Map.! traceName) <$> readIORef traceMap#+  let (tRep, _period, _width, samples) = replaySignal+  pure (ByteStringLazy.concat (tRep : map encode (take n samples)))++-- | Take a serialized signal (dumped with @dumpReplayable@) and convert it+-- back into a signal. Will error if dumped type does not match requested+-- type. The first value in the signal that fails to decode will stop the+-- decoding process and yield an error. Not that this always happens if you+-- evaluate more values than were originally dumped.+replay+  :: forall a dom n+   . ( Typeable a+     , NFDataX a+     , BitPack a+     , KnownNat n+     , n ~ BitSize a )+  => ByteString+  -> Either String (Signal dom a)+replay bytes0 = samples1+ where+  samples1 =+    case decodeOrFail bytes0 of+      Left (_, _, err) ->+        Left ("Failed to decode typeRep. Parser reported:\n\n" ++ err)+      Right (bytes1, _, _ :: TypeRep a) ->+        let samples0 = decodeSamples bytes1 in+        let err = "Failed to decode value in signal. Parser reported:\n\n " in+        Right (fromList (map (either (error . (err ++)) id) samples0))++-- | Helper function of 'replay'. Decodes ByteString to some type with+-- BitVector as an intermediate type.+decodeSamples+  :: forall a n+   . ( BitPack a+     , KnownNat n+     , n ~ BitSize a )+  => ByteString+  -> [Either String a]+decodeSamples bytes0 =+  case decodeOrFail bytes0 of+    Left (_, _, err) ->+      [Left err]+    Right (bytes1, _, (m, v)) ->+      (Right (unpack (BV m v))) : decodeSamples bytes1++-- | Keep evaluating given signal until all trace names are present.+waitForTraces#+  :: NFDataX a+  => IORef TraceMap+  -- ^ Map with collected traces+  -> Signal dom a+  -- ^ (One of) the output(s) the circuit containing the traces+  -> [String]+  -- ^ The names of the traces you definitely want to be dumped to the VCD file+  -> IO ()+waitForTraces# traceMap signal traceNames = do+  atomicWriteIORef traceMap Map.empty+  rest <- foldM go (sample signal) traceNames+  return $ deepseqX (head rest) ()+ where+  go s nm = do+    m <- readIORef traceMap+    if Map.member nm m then+      return s+    else+      deepseqX+        (head s)+        (go (tail s) nm)
src/Clash/Sized/BitVector.hs view
@@ -27,6 +27,8 @@   , bLit     -- ** Concatenation   , (++#)+    -- ** Pattern matching+  , bitPattern   ) where 
src/Clash/Sized/Fixed.hs view
@@ -51,11 +51,11 @@   , divide     -- * Compile-time 'Double' conversion   , fLit-    -- * Run-time 'Double' conversion (not synthesisable)+    -- * Run-time 'Double' conversion (not synthesizable)   , fLitR     -- * 'Fixed' point wrapper   , Fixed (..), resizeF, fracShift-    -- * Constraint synonyms+    -- * Constraint synonyms #constraintsynonyms#     -- $constraintsynonyms      -- ** Constraint synonyms for 'SFixed'@@ -73,7 +73,8 @@ import Control.Arrow              ((***), second) import Data.Bits                  (Bits (..), FiniteBits) import Data.Data                  (Data)-import Data.Default               (Default (..))+import Data.Default.Class         (Default (..))+import Data.Either                (isLeft) import Text.Read                  (Read(..)) import Data.List                  (find) import Data.Maybe                 (fromJust)@@ -89,8 +90,8 @@  import Clash.Class.BitPack        (BitPack (..)) import Clash.Class.Num            (ExtendingNum (..), SaturatingNum (..),-                                   SaturationMode (..), boundedPlus, boundedMin,-                                   boundedMult)+                                   SaturationMode (..), boundedAdd, boundedSub,+                                   boundedMul) import Clash.Class.Resize         (Resize (..)) import Clash.Promoted.Nat         (SNat) import Clash.Prelude.BitIndex     (msb, split)@@ -98,7 +99,8 @@ import Clash.Sized.BitVector      (BitVector, (++#)) import Clash.Sized.Signed         (Signed) import Clash.Sized.Unsigned       (Unsigned)-import Clash.XException           (ShowX (..), showsPrecXWith)+import Clash.XException+  (ShowX (..), NFDataX (..), isX, errorX, showsPrecXWith)  {- $setup >>> :set -XDataKinds@@ -135,7 +137,7 @@ deriving instance FiniteBits (rep (int + frac)) => FiniteBits (Fixed rep int frac)  -- | Instance functions do not saturate.--- Meaning that \"@`'shiftL'` 1 == 'satMult' 'SatWrap' 2'@\""+-- Meaning that \"@\`shiftL\` 1 == 'satMul' 'SatWrap' 2'@\" deriving instance Bits (rep (int + frac)) => Bits (Fixed rep int frac)  -- | Signed 'Fixed'-point number, with @int@ integer bits (including sign-bit)@@ -161,11 +163,11 @@ -- -4.0 -- >>> 1.375 * (-0.8125) :: SFixed 3 4 -- -1.125--- >>> (1.375 :: SFixed 3 4) `times` (-0.8125 :: SFixed 3 4) :: SFixed 6 8+-- >>> (1.375 :: SFixed 3 4) `mul` (-0.8125 :: SFixed 3 4) :: SFixed 6 8 -- -1.1171875--- >>> (2 :: SFixed 3 4) `plus` (3 :: SFixed 3 4) :: SFixed 4 4+-- >>> (2 :: SFixed 3 4) `add` (3 :: SFixed 3 4) :: SFixed 4 4 -- 5.0--- >>> (-2 :: SFixed 3 4) `plus` (-3 :: SFixed 3 4) :: SFixed 4 4+-- >>> (-2 :: SFixed 3 4) `add` (-3 :: SFixed 3 4) :: SFixed 4 4 -- -5.0 type SFixed = Fixed Signed @@ -189,14 +191,14 @@ -- 0.0 -- >>> 1.375 * 0.8125 :: UFixed 3 4 -- 1.0625--- >>> (1.375 :: UFixed 3 4) `times` (0.8125 :: UFixed 3 4) :: UFixed 6 8+-- >>> (1.375 :: UFixed 3 4) `mul` (0.8125 :: UFixed 3 4) :: UFixed 6 8 -- 1.1171875--- >>> (2 :: UFixed 3 4) `plus` (6 :: UFixed 3 4) :: UFixed 4 4+-- >>> (2 :: UFixed 3 4) `add` (6 :: UFixed 3 4) :: UFixed 4 4 -- 8.0 ----- However, 'minus' does not saturate to 'minBound' on underflow:+-- However, 'sub' does not saturate to 'minBound' on underflow: ----- >>> (1 :: UFixed 3 4) `minus` (3 :: UFixed 3 4) :: UFixed 4 4+-- >>> (1 :: UFixed 3 4) `sub` (3 :: UFixed 3 4) :: UFixed 4 4 -- 14.0 type UFixed = Fixed Unsigned @@ -205,9 +207,12 @@ -- -- >>> sf d4 (-22 :: Signed 7) -- -1.375-sf :: SNat frac           -- ^ Position of the virtual @point@-   -> Signed (int + frac) -- ^ The 'Signed' integer-   -> SFixed int frac+sf+  :: SNat frac+  -- ^ Position of the virtual @point@+  -> Signed (int + frac)+  -- ^ The 'Signed' integer+  -> SFixed int frac sf _ fRep = Fixed fRep  {-# INLINE unSF #-}@@ -221,9 +226,12 @@ -- -- >>> uf d4 (92 :: Unsigned 7) -- 5.75-uf :: SNat frac             -- ^ Position of the virtual @point@-   -> Unsigned (int + frac) -- ^ The 'Unsigned' integer-   -> UFixed int frac+uf+  :: SNat frac+  -- ^ Position of the virtual @point@+  -> Unsigned (int + frac)+  -- ^ The 'Unsigned' integer+  -> UFixed int frac uf _ fRep = Fixed fRep  {-# INLINE unUF #-}@@ -268,12 +276,16 @@          ) => ShowX (Fixed rep int frac) where   showsPrecX = showsPrecXWith showsPrec --- | None of the 'Read' class' methods are synthesisable.+instance NFDataX (rep (int + frac)) => NFDataX (Fixed rep int frac) where+  deepErrorX = Fixed . errorX+  rnfX f@(~(Fixed x)) = if isLeft (isX f) then () else rnfX x++-- | None of the 'Read' class' methods are synthesizable. instance (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size))       => Read (Fixed rep int frac) where   readPrec = fLitR <$> readPrec -{- $constraintsynonyms #constraintsynonyms#+{- $constraintsynonyms Writing polymorphic functions over fixed point numbers can be a potentially verbose due to the many class constraints induced by the functions and operators of this module.@@ -337,7 +349,7 @@      -> 'SFixed' int2 frac2      -> 'SFixed' int3 frac3      -> 'SFixed' (1 + Max (int1 + int2) int3) (Max (frac1 + frac2) frac3)-mac2 x y s = (x \`times\` y) \`plus\` s+mac2 x y s = (x \`mul\` y) \`add\` s @  Which, with the proper constraint kinds can be reduced to:@@ -350,7 +362,7 @@      -> 'SFixed' int2 frac2      -> 'SFixed' int3 frac3      -> 'SFixed' (1 + Max (int1 + int2) int3) (Max (frac1 + frac2) frac3)-mac3 x y s = (x \`times\` y) \`plus\` s+mac3 x y s = (x \`mul\` y) \`add\` s @ -} @@ -397,13 +409,13 @@   ExtendingNum (Fixed rep int1 frac1) (Fixed rep int2 frac2) where   type AResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) =                Fixed rep (1 + Max int1 int2) (Max frac1 frac2)-  plus (Fixed f1) (Fixed f2) =+  add (Fixed f1) (Fixed f2) =     let sh1 = fromInteger (natVal (Proxy @(Max frac1 frac2)) - natVal (Proxy @frac1)) :: Int         f1R = shiftL (resize f1) sh1 :: rep ((1 + Max int1 int2) + (Max frac1 frac2))         sh2 = fromInteger (natVal (Proxy @(Max frac1 frac2)) - natVal (Proxy @frac2)) :: Int         f2R = shiftL (resize f2) sh2 :: rep ((1 + Max int1 int2) + (Max frac1 frac2))     in  Fixed (f1R + f2R)-  minus (Fixed f1) (Fixed f2) =+  sub (Fixed f1) (Fixed f2) =     let sh1 = fromInteger (natVal (Proxy @(Max frac1 frac2)) - natVal (Proxy @frac1)) :: Int         f1R = shiftL (resize f1) sh1 :: rep ((1 + Max int1 int2) + (Max frac1 frac2))         sh2 = fromInteger (natVal (Proxy @(Max frac1 frac2)) - natVal (Proxy @frac2)) :: Int@@ -411,7 +423,7 @@     in  Fixed (f1R - f2R)   type MResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) =                Fixed rep (int1 + int2) (frac1 + frac2)-  times (Fixed fRep1) (Fixed fRep2) = Fixed (times fRep1 fRep2)+  mul (Fixed fRep1) (Fixed fRep2) = Fixed (mul fRep1 fRep2)  -- | Constraint for the 'Num' instance of 'Fixed' type NumFixedC rep int frac@@ -427,6 +439,7 @@     , BitPack (rep (int + frac))     , Enum    (rep (int + frac))     , Bits    (rep (int + frac))+    , Ord     (rep (int + frac))     , Resize  rep     , KnownNat int     , KnownNat frac@@ -457,12 +470,15 @@ -- * @'NumSFixedC' int frac@     for: @'SFixed' int frac@ -- * @'NumUFixedC' int frac@     for: @'UFixed' int frac@ instance (NumFixedC rep int frac) => Num (Fixed rep int frac) where-  (+)              = boundedPlus-  (*)              = boundedMult-  (-)              = boundedMin+  (+)              = boundedAdd+  (*)              = boundedMul+  (-)              = boundedSub   negate (Fixed a) = Fixed (negate a)   abs    (Fixed a) = Fixed (abs a)-  signum (Fixed a) = Fixed (signum a)+  signum (Fixed a)+    | a == 0       = 0+    | a <  0       = -1+    | otherwise    = 1   fromInteger i    = let fSH = fromInteger (natVal (Proxy @frac))                          res = Fixed (fromInteger i `shiftL` fSH)                      in  res@@ -539,9 +555,11 @@ -- -- * @'ResizeUFC' rep int1 frac1 int2 frac2@ for: --   @'UFixed' int1 frac1 -> 'UFixed' int2 frac2@-resizeF :: forall rep int1 frac1 int2 frac2 . ResizeFC rep int1 frac1 int2 frac2-        => Fixed rep int1 frac1-        -> Fixed rep int2 frac2+resizeF+  :: forall rep int1 frac1 int2 frac2+   . ResizeFC rep int1 frac1 int2 frac2+  => Fixed rep int1 frac1+  -> Fixed rep int2 frac2 resizeF (Fixed fRep) = Fixed sat   where     fMin  = minBound :: rep (int2 + frac2)@@ -619,11 +637,14 @@ -- 0.1953125 -- >>> $$(fLit (atan 0.2)) :: SFixed 1 20 -- 0.19739532470703125-fLit :: forall rep int frac size .-        ( size ~ (int + frac), KnownNat frac, Bounded (rep size)-        , Integral (rep size))-     => Double-     -> Q (TExp (Fixed rep int frac))+fLit+  :: forall rep int frac size+   . ( size ~ (int + frac)+     , KnownNat frac+     , Bounded (rep size)+     , Integral (rep size) )+  => Double+  -> Q (TExp (Fixed rep int frac)) fLit a = [|| Fixed (fromInteger sat) ||]   where     rMax      = toInteger (maxBound :: rep size)@@ -638,13 +659,13 @@  -- | Convert, at run-time, a 'Double' to a 'Fixed'-point. ----- __NB__: this functions is /not/ synthesisable+-- __NB__: this functions is /not/ synthesizable -- -- = Creating data-files #creatingdatafiles# -- -- An example usage of this function is for example to convert a data file -- containing 'Double's to a data file with ASCI-encoded binary numbers to be--- used by a synthesisable function like 'Clash.Prelude.ROM.File.asyncRomFile'.+-- used by a synthesizable function like 'Clash.Prelude.ROM.File.asyncRomFile'. -- For example, given a file @Data.txt@ containing: -- -- @@@ -665,8 +686,12 @@ -- import System.Environment -- import qualified Data.List as L ----- createRomFile :: KnownNat n => (Double -> BitVector n)---               -> FilePath -> FilePath -> IO ()+-- createRomFile+--   :: KnownNat n+--   => (Double -> BitVector n)+--   -> FilePath+--   -> FilePath+--   -> IO () -- createRomFile convert fileR fileW = do --   f <- readFile fileR --   let ds :: [Double]@@ -784,11 +809,14 @@ -- __>>> romF' 0 0__ -- 1.19921875 -- @-fLitR :: forall rep int frac size .-         ( size ~ (int + frac), KnownNat frac, Bounded (rep size)-         , Integral (rep size))-      => Double-      -> Fixed rep int frac+fLitR+  :: forall rep int frac size+   . ( size ~ (int + frac)+     , KnownNat frac+     , Bounded (rep size)+     , Integral (rep size))+  => Double+  -> Fixed rep int frac fLitR a = Fixed (fromInteger sat)   where     rMax      = toInteger (maxBound :: rep size)@@ -802,17 +830,17 @@     shifted   = a * (2 ^ (natVal (Proxy @frac)))  instance NumFixedC rep int frac => SaturatingNum (Fixed rep int frac) where-  satPlus w (Fixed a) (Fixed b) = Fixed (satPlus w a b)-  satMin  w (Fixed a) (Fixed b) = Fixed (satMin w a b)+  satAdd w (Fixed a) (Fixed b) = Fixed (satAdd w a b)+  satSub  w (Fixed a) (Fixed b) = Fixed (satSub w a b) -  satMult SatWrap (Fixed a) (Fixed b) =-    let res  = a `times` b+  satMul SatWrap (Fixed a) (Fixed b) =+    let res  = a `mul` b         sh   = fromInteger (natVal (Proxy @frac))         res' = shiftR res sh     in  Fixed (resize res') -  satMult SatBound (Fixed a) (Fixed b) =-    let res     = a `times` b+  satMul SatBound (Fixed a) (Fixed b) =+    let res     = a `mul` b         sh      = fromInteger (natVal (Proxy @frac))         (rL,rR) = split res :: (BitVector int, BitVector (int + frac + frac))     in  case isSigned a of@@ -827,8 +855,8 @@                      0 -> unpack (resize (shiftR rR sh))                      _ -> maxBound -  satMult SatZero (Fixed a) (Fixed b) =-    let res     = a `times` b+  satMul SatZero (Fixed a) (Fixed b) =+    let res     = a `mul` b         sh      = fromInteger (natVal (Proxy @frac))         (rL,rR) = split res :: (BitVector int, BitVector (int + frac + frac))     in  case isSigned a of@@ -841,8 +869,8 @@                      0 -> unpack (resize (shiftR rR sh))                      _ -> 0 -  satMult SatSymmetric (Fixed a) (Fixed b) =-    let res     = a `times` b+  satMul SatSymmetric (Fixed a) (Fixed b) =+    let res     = a `mul` b         sh      = fromInteger (natVal (Proxy @frac))         (rL,rR) = split res :: (BitVector int, BitVector (int + frac + frac))     in  case isSigned a of@@ -894,10 +922,11 @@ -- -- * @'DivideUC' rep int1 frac1 int2 frac2@ for: --   @'UFixed' int1 frac1 -> 'UFixed' int2 frac2 -> 'UFixed' (int1 + frac2 + 1) (int2 + frac1)@-divide :: DivideC rep int1 frac1 int2 frac2-       => Fixed rep int1 frac1-       -> Fixed rep int2 frac2-       -> Fixed rep (int1 + frac2 + 1) (int2 + frac1)+divide+  :: DivideC rep int1 frac1 int2 frac2+  => Fixed rep int1 frac1+  -> Fixed rep int2 frac2+  -> Fixed rep (int1 + frac2 + 1) (int2 + frac1) divide (Fixed fr1) fx2@(Fixed fr2) =   let int2  = fromInteger (natVal (asIntProxy fx2))       frac2 = fromInteger (natVal fx2)@@ -961,3 +990,11 @@      nF        = fracShift f      denom     = 1 `shiftL` nF      nom       = toInteger fRep++instance (FracFixedC rep int frac, NumFixedC rep int frac, Integral (rep (int + frac))) =>+         RealFrac (Fixed rep int frac) where+  properFraction f@(Fixed fRep) = (fromIntegral whole, fract)+    where+      whole = (fRep `shiftR` fracShift f) + offset+      fract = Fixed $ fRep - (whole `shiftL` fracShift f)+      offset = if f < 0 then 1 else 0
src/Clash/Sized/Index.hs view
@@ -11,6 +11,7 @@ {-# LANGUAGE Trustworthy #-}  {-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise  #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-} {-# OPTIONS_HADDOCK show-extensions #-} 
src/Clash/Sized/Internal/BitVector.hs view
@@ -1,13 +1,15 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2016     , Myrtle Software Ltd+                  2019     , Gergő Érdi+                  2016-2019, Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}  {-# LANGUAGE DataKinds                  #-} {-# LANGUAGE DeriveDataTypeable         #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE DeriveAnyClass             #-} {-# LANGUAGE KindSignatures             #-} {-# LANGUAGE MagicHash                  #-} {-# LANGUAGE MultiParamTypeClasses      #-}@@ -17,6 +19,7 @@ {-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE TypeOperators              #-} {-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}  {-# LANGUAGE Unsafe #-} @@ -56,6 +59,7 @@   , maxIndex#     -- ** Construction   , bLit+  , undefined#     -- ** Concatenation   , (++#)     -- ** Reduction@@ -74,12 +78,13 @@     -- **** Eq   , eq#   , neq#+  , isLike     -- *** Ord   , lt#   , ge#   , gt#   , le#-    -- *** Enum (not synthesisable)+    -- *** Enum (not synthesizable)   , enumFrom#   , enumFromThen#   , enumFromTo#@@ -115,27 +120,32 @@   , countLeadingZerosBV   , countTrailingZerosBV     -- *** Resize-  , resize#+  , truncateB#     -- *** QuickCheck   , shrinkSizedUnsigned+  -- ** Other+  , undefError+  , checkUnpackUndef+  , bitPattern   ) where  import Control.DeepSeq            (NFData (..)) import Control.Lens               (Index, Ixed (..), IxValue) import Data.Bits                  (Bits (..), FiniteBits (..))-import Data.Char                  (digitToInt) import Data.Data                  (Data)-import Data.Default               (Default (..))-import Data.Maybe                 (listToMaybe)+import Data.Default.Class         (Default (..)) import Data.Proxy                 (Proxy (..))+import Data.Typeable              (Typeable, typeOf)+import GHC.Generics               (Generic)+import Data.Maybe                 (fromMaybe) import GHC.Integer                (smallInteger) import GHC.Prim                   (dataToTag#)+import GHC.Stack                  (HasCallStack, withFrozenCallStack) import GHC.TypeLits               (KnownNat, Nat, type (+), type (-), natVal) import GHC.TypeLits.Extra         (Max)-import Language.Haskell.TH        (Q, TExp, TypeQ, appT, conT, litT, numTyLit, sigE)+import Language.Haskell.TH        (Q, TExp, TypeQ, appT, conT, litT, numTyLit, sigE, Lit(..), litE, Pat, litP) import Language.Haskell.TH.Syntax (Lift(..))-import Numeric                    (readInt) import Test.QuickCheck.Arbitrary  (Arbitrary (..), CoArbitrary (..),                                    arbitraryBoundedIntegral,                                    coarbitraryIntegral, shrinkIntegral)@@ -143,11 +153,14 @@ import Clash.Class.Num            (ExtendingNum (..), SaturatingNum (..),                                    SaturationMode (..)) import Clash.Class.Resize         (Resize (..))-import Clash.Promoted.Nat         (SNat, snatToInteger, snatToNum)-import Clash.XException           (ShowX (..), showsPrecXWith)+import Clash.Promoted.Nat+  (SNat (..), SNatLE (..), compareSNat, snatToInteger, snatToNum)+import Clash.XException+  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)  import {-# SOURCE #-} qualified Clash.Sized.Vector         as V import {-# SOURCE #-} qualified Clash.Sized.Internal.Index as I+import                qualified Data.List                  as L  {- $setup >>> :set -XTemplateHaskell@@ -160,49 +173,58 @@ -- -- * Bit indices are descending -- * 'Num' instance performs /unsigned/ arithmetic.-newtype BitVector (n :: Nat) =+data BitVector (n :: Nat) =     -- | The constructor, 'BV', and  the field, 'unsafeToInteger', are not-    -- synthesisable.-    BV { unsafeToInteger :: Integer}-  deriving (Data)+    -- synthesizable.+    BV { unsafeMask      :: !Integer+       , unsafeToInteger :: !Integer+       }+  deriving (Data, Generic)  -- * Bit  -- | Bit-newtype Bit =+data Bit =   -- | The constructor, 'Bit', and  the field, 'unsafeToInteger#', are not-  -- synthesisable.-  Bit { unsafeToInteger# :: Integer}-  deriving (Data)+  -- synthesizable.+  Bit { unsafeMask#      :: !Integer+      , unsafeToInteger# :: !Integer+      }+  deriving (Data, Generic)  -- * Constructions -- ** Initialisation {-# NOINLINE high #-} -- | logic '1' high :: Bit-high = Bit 1+high = Bit 0 1  {-# NOINLINE low #-} -- | logic '0' low :: Bit-low = Bit 0+low = Bit 0 0  -- ** Instances instance NFData Bit where-  rnf (Bit i) = rnf i `seq` ()+  rnf (Bit m i) = rnf m `seq` rnf i `seq` ()   {-# NOINLINE rnf #-}  instance Show Bit where-  show (Bit b) =-    case b of-      0 -> "0"-      _ -> "1"+  show (Bit 0 b) =+    case testBit b 0 of+      True  -> "1"+      False -> "0"+  show (Bit _ _) = "."  instance ShowX Bit where   showsPrecX = showsPrecXWith showsPrec +instance NFDataX Bit where+  deepErrorX = errorX+  rnfX = rwhnfX+ instance Lift Bit where-  lift (Bit i) = if i == 0 then [| low |] else [| high |]+  lift (Bit m i) = [| fromInteger## m i |]   {-# NOINLINE lift #-}  instance Eq Bit where@@ -210,11 +232,11 @@   (/=) = neq##  eq## :: Bit -> Bit -> Bool-eq## (Bit b1) (Bit b2) = b1 == b2+eq## b1 b2 = eq# (pack# b1) (pack# b2) {-# NOINLINE eq## #-}  neq## :: Bit -> Bit -> Bool-neq## (Bit b1) (Bit b2) = b1 == b2+neq## b1 b2 = neq# (pack# b1) (pack# b2) {-# NOINLINE neq## #-}  instance Ord Bit where@@ -224,17 +246,17 @@   (>=) = ge##  lt##,ge##,gt##,le## :: Bit -> Bit -> Bool-lt## (Bit n) (Bit m) = n < m+lt## b1 b2 = lt# (pack# b1) (pack# b2) {-# NOINLINE lt## #-}-ge## (Bit n) (Bit m) = n >= m+ge## b1 b2 = ge# (pack# b1) (pack# b2) {-# NOINLINE ge## #-}-gt## (Bit n) (Bit m) = n > m+gt## b1 b2 = gt# (pack# b1) (pack# b2) {-# NOINLINE gt## #-}-le## (Bit n) (Bit m) = n <= m+le## b1 b2 = le# (pack# b1) (pack# b2) {-# NOINLINE le## #-}  instance Enum Bit where-  toEnum     = fromInteger## . toInteger+  toEnum     = fromInteger## 0 . toInteger   fromEnum b = if eq## b low then 0 else 1  instance Bounded Bit where@@ -251,10 +273,10 @@   negate      = complement##   abs         = id   signum b    = b-  fromInteger = fromInteger##+  fromInteger = fromInteger## 0 -fromInteger## :: Integer -> Bit-fromInteger## i = Bit (i `mod` 2)+fromInteger## :: Integer -> Integer -> Bit+fromInteger## m i = Bit (m `mod` 2) (i `mod` 2) {-# NOINLINE fromInteger## #-}  instance Real Bit where@@ -276,8 +298,8 @@   complement        = complement##   zeroBits          = low   bit i             = if i == 0 then high else low-  setBit _ i        = if i == 0 then high else low-  clearBit _ i      = if i == 0 then low  else high+  setBit b i        = if i == 0 then high else b+  clearBit b i      = if i == 0 then low  else b   complementBit b i = if i == 0 then complement## b else b   testBit b i       = if i == 0 then eq## b high else False   bitSizeMaybe _    = Just 1@@ -295,44 +317,45 @@   countTrailingZeros b = if eq## b low then 1 else 0  and##, or##, xor## :: Bit -> Bit -> Bit-and## (Bit v1) (Bit v2) = Bit (v1 .&. v2)+and## b1 b2 = unpack# $ and# (pack# b1) (pack# b2) {-# NOINLINE and## #-} -or## (Bit v1) (Bit v2) = Bit (v1 .|. v2)+or## b1 b2 = unpack# $ or# (pack# b1) (pack# b2) {-# NOINLINE or## #-} -xor## (Bit v1) (Bit v2) = Bit (v1 `xor` v2)+xor## b1 b2 = unpack# $ xor# (pack# b1) (pack# b2) {-# NOINLINE xor## #-}  complement## :: Bit -> Bit-complement## (Bit 0) = Bit 1-complement## _       = Bit 0+complement## = unpack# . complement# . pack# {-# NOINLINE complement## #-}  -- *** BitPack pack# :: Bit -> BitVector 1-pack# (Bit b) = BV b+pack# (Bit m b) = BV m b {-# NOINLINE pack# #-}  unpack# :: BitVector 1 -> Bit-unpack# (BV b) = Bit b+unpack# (BV m b) = Bit m b {-# NOINLINE unpack# #-}  -- * Instances instance NFData (BitVector n) where-  rnf (BV i) = rnf i `seq` ()+  rnf (BV i m) = rnf i `seq` rnf m `seq` ()   {-# NOINLINE rnf #-}   -- NOINLINE is needed so that Clash doesn't trip on the "BitVector ~# Integer"   -- coercion  instance KnownNat n => Show (BitVector n) where-  show bv@(BV i) = reverse . underScore . reverse $ showBV (natVal bv) i []+  show bv@(BV msk i) = reverse . underScore . reverse $ showBV (natVal bv) msk i []     where-      showBV 0 _ s = s-      showBV n v s = let (a,b) = divMod v 2-                     in  case b of-                           1 -> showBV (n - 1) a ('1':s)-                           _ -> showBV (n - 1) a ('0':s)+      showBV 0 _ _ s = s+      showBV n m v s = let (v',vBit) = divMod v 2+                           (m',mBit) = divMod m 2+                       in  case (mBit,vBit) of+                           (0,0) -> showBV (n - 1) m' v' ('0':s)+                           (0,_) -> showBV (n - 1) m' v' ('1':s)+                           _     -> showBV (n - 1) m' v' ('.':s)        underScore xs = case splitAt 5 xs of                         ([a,b,c,d,e],rest) -> [a,b,c,d,'_'] ++ underScore (e:rest)@@ -342,6 +365,10 @@ instance KnownNat n => ShowX (BitVector n) where   showsPrecX = showsPrecXWith showsPrec +instance NFDataX (BitVector n) where+  deepErrorX = errorX+  rnfX = rwhnfX+ -- | Create a binary literal -- -- >>> $$(bLit "1001") :: BitVector 4@@ -360,51 +387,74 @@ -- >>> import qualified Data.List as List -- >>> $$(bLit (List.replicate 4 '1')) :: BitVector 4 -- 1111-bLit :: KnownNat n => String -> Q (TExp (BitVector n))-bLit s = [|| fromInteger# i' ||]+--+-- Also 'bLit' can handle don't care bits:+--+-- >>> $$(bLit "1.0.") :: BitVector 4+-- 1.0.+bLit :: forall n. KnownNat n => String -> Q (TExp (BitVector n))+bLit s = [|| fromInteger# m i ||]   where-    i :: Maybe Integer-    i = fmap fst . listToMaybe . (readInt 2 (`elem` "01") digitToInt) $ filter (/= '_') s+    bv :: BitVector n+    bv = read# s -    i' :: Integer-    i' = case i of-           Just j -> j-           _      -> error "Failed to parse: " s+    m,i :: Integer+    BV m i = bv -instance Eq (BitVector n) where+read# :: KnownNat n => String -> BitVector n+read# cs = BV m v+  where+    (vs,ms) = unzip . map readBit . filter (/= '_') $ cs+    combineBits = foldl (\b a -> b*2+a) 0+    v = combineBits vs+    m = combineBits ms+    readBit c = case c of+      '0' -> (0,0)+      '1' -> (1,0)+      '.' -> (0,1)+      _   -> error $ "Clash.Sized.Internal.bLit: unknown character: " ++ show c ++ " in input: " ++ cs+++instance KnownNat n => Eq (BitVector n) where   (==) = eq#   (/=) = neq#  {-# NOINLINE eq# #-}-eq# :: BitVector n -> BitVector n -> Bool-eq# (BV v1) (BV v2) = v1 == v2+eq# :: KnownNat n => BitVector n -> BitVector n -> Bool+eq# (BV 0 v1) (BV 0 v2 ) = v1 == v2+eq# bv1 bv2 = undefErrorI "==" bv1 bv2  {-# NOINLINE neq# #-}-neq# :: BitVector n -> BitVector n -> Bool-neq# (BV v1) (BV v2) = v1 /= v2+neq# :: KnownNat n => BitVector n -> BitVector n -> Bool+neq# (BV 0 v1) (BV 0 v2) = v1 /= v2+neq# bv1 bv2 = undefErrorI "/=" bv1 bv2 -instance Ord (BitVector n) where+instance KnownNat n => Ord (BitVector n) where   (<)  = lt#   (>=) = ge#   (>)  = gt#   (<=) = le# -lt#,ge#,gt#,le# :: BitVector n -> BitVector n -> Bool+lt#,ge#,gt#,le# :: KnownNat n => BitVector n -> BitVector n -> Bool {-# NOINLINE lt# #-}-lt# (BV n) (BV m) = n < m+lt# (BV 0 n) (BV 0 m) = n < m+lt# bv1 bv2 = undefErrorI "<" bv1 bv2 {-# NOINLINE ge# #-}-ge# (BV n) (BV m) = n >= m+ge# (BV 0 n) (BV 0 m) = n >= m+ge# bv1 bv2 = undefErrorI ">=" bv1 bv2 {-# NOINLINE gt# #-}-gt# (BV n) (BV m) = n > m+gt# (BV 0 n) (BV 0 m) = n > m+gt# bv1 bv2 = undefErrorI ">" bv1 bv2 {-# NOINLINE le# #-}-le# (BV n) (BV m) = n <= m+le# (BV 0 n) (BV 0 m) = n <= m+le#  bv1 bv2 = undefErrorI "<=" bv1 bv2  -- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and--- 'enumFromThenTo', are not synthesisable.+-- 'enumFromThenTo', are not synthesizable. instance KnownNat n => Enum (BitVector n) where-  succ           = (+# fromInteger# 1)-  pred           = (-# fromInteger# 1)-  toEnum         = fromInteger# . toInteger+  succ           = (+# fromInteger# 0 1)+  pred           = (-# fromInteger# 0 1)+  toEnum         = fromInteger# 0 . toInteger   fromEnum       = fromEnum . toInteger#   enumFrom       = enumFrom#   enumFromThen   = enumFromThen#@@ -417,25 +467,38 @@ {-# NOINLINE enumFromThenTo# #-} enumFrom#       :: KnownNat n => BitVector n -> [BitVector n] enumFromThen#   :: KnownNat n => BitVector n -> BitVector n -> [BitVector n]-enumFromTo#     :: BitVector n -> BitVector n -> [BitVector n]-enumFromThenTo# :: BitVector n -> BitVector n -> BitVector n -> [BitVector n]-enumFrom# x             = map fromInteger_INLINE [unsafeToInteger x ..]-enumFromThen# x y       = map fromInteger_INLINE [unsafeToInteger x, unsafeToInteger y ..]-enumFromTo# x y         = map BV [unsafeToInteger x .. unsafeToInteger y]-enumFromThenTo# x1 x2 y = map BV [unsafeToInteger x1, unsafeToInteger x2 .. unsafeToInteger y]+enumFromTo#     :: KnownNat n => BitVector n -> BitVector n -> [BitVector n]+enumFromThenTo# :: KnownNat n => BitVector n -> BitVector n -> BitVector n -> [BitVector n] +enumFrom# (BV 0 x)                           = map (fromInteger_INLINE 0) [x ..]+enumFrom# bv+  = undefErrorU "enumFrom" bv++enumFromThen# (BV 0 x) (BV 0 y)              = map (fromInteger_INLINE 0) [x, y ..]+enumFromThen# bv1 bv2+  = undefErrorP "enumFromThen" bv1 bv2++enumFromTo# (BV 0 x) (BV 0 y)                = map (BV 0) [x .. y]+enumFromTo# bv1 bv2+  = undefErrorP "enumFromTo" bv1 bv2++enumFromThenTo# (BV 0 x1) (BV 0 x2) (BV 0 y) = map (BV 0) [x1, x2 .. y]+enumFromThenTo# bv1 bv2 bv3+  = undefErrorP3 "enumFromTo" bv1 bv2 bv3++ instance KnownNat n => Bounded (BitVector n) where   minBound = minBound#   maxBound = maxBound#  {-# NOINLINE minBound# #-} minBound# :: BitVector n-minBound# = BV 0+minBound# = BV 0 0  {-# NOINLINE maxBound# #-} maxBound# :: forall n . KnownNat n => BitVector n maxBound# = let m = 1 `shiftL` fromInteger (natVal (Proxy @n))-            in  BV (m-1)+            in  BV 0 (m-1)  instance KnownNat n => Num (BitVector n) where   (+)         = (+#)@@ -443,63 +506,72 @@   (*)         = (*#)   negate      = negate#   abs         = id-  signum bv   = resize# (pack# (reduceOr# bv))-  fromInteger = fromInteger#+  signum bv   = resizeBV (pack# (reduceOr# bv))+  fromInteger = fromInteger# 0  (+#),(-#),(*#) :: forall n . KnownNat n => BitVector n -> BitVector n -> BitVector n {-# NOINLINE (+#) #-}-(+#) (BV i) (BV j) = let m = 1 `shiftL` fromInteger (natVal (Proxy @n))-                         z = i + j-                     in  if z >= m then BV (z - m) else BV z+(+#) (BV 0 i) (BV 0 j) =+  let m = 1 `shiftL` fromInteger (natVal (Proxy @n))+      z = i + j+  in  if z >= m then BV 0 (z - m) else BV 0 z+(+#) bv1 bv2 = undefErrorI "+" bv1 bv2  {-# NOINLINE (-#) #-}-(-#) (BV i) (BV j) = let m = 1 `shiftL` fromInteger (natVal (Proxy @n))-                         z = i - j-                     in  if z < 0 then BV (m + z) else BV z+(-#) (BV 0 i) (BV 0 j) =+  let m = 1 `shiftL` fromInteger (natVal (Proxy @n))+      z = i - j+  in  if z < 0 then BV 0 (m + z) else BV 0 z+(-#) bv1 bv2 = undefErrorI "-" bv1 bv2  {-# NOINLINE (*#) #-}-(*#) (BV i) (BV j) = fromInteger_INLINE (i * j)+(*#) (BV 0 i) (BV 0 j) = fromInteger_INLINE 0 (i * j)+(*#) bv1 bv2 = undefErrorI "*" bv1 bv2  {-# NOINLINE negate# #-} negate# :: forall n . KnownNat n => BitVector n -> BitVector n-negate# (BV 0) = BV 0-negate# (BV i) = BV (sz - i)+negate# (BV 0 0) = BV 0 0+negate# (BV 0 i) = BV 0 (sz - i)   where     sz = 1 `shiftL` fromInteger (natVal (Proxy @n))+negate# bv = undefErrorU "negate" bv  {-# NOINLINE fromInteger# #-}-fromInteger# :: KnownNat n => Integer -> BitVector n+fromInteger# :: KnownNat n => Integer -> Integer -> BitVector n fromInteger# = fromInteger_INLINE  {-# INLINE fromInteger_INLINE #-}-fromInteger_INLINE :: forall n . KnownNat n => Integer -> BitVector n-fromInteger_INLINE i = sz `seq` BV (i `mod` sz)+fromInteger_INLINE :: forall n . KnownNat n => Integer -> Integer -> BitVector n+fromInteger_INLINE m i = sz `seq` BV (m `mod` sz) (i `mod` sz)   where     sz = 1 `shiftL` fromInteger (natVal (Proxy @n))  instance (KnownNat m, KnownNat n) => ExtendingNum (BitVector m) (BitVector n) where   type AResult (BitVector m) (BitVector n) = BitVector (Max m n + 1)-  plus  = plus#-  minus = minus#+  add  = plus#+  sub = minus#   type MResult (BitVector m) (BitVector n) = BitVector (m + n)-  times = times#+  mul = times#  {-# NOINLINE plus# #-}-plus# :: BitVector m -> BitVector n -> BitVector (Max m n + 1)-plus# (BV a) (BV b) = BV (a + b)+plus# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (Max m n + 1)+plus# (BV 0 a) (BV 0 b) = BV 0 (a + b)+plus# bv1 bv2 = undefErrorP "plus" bv1 bv2  {-# NOINLINE minus# #-} minus# :: forall m n . (KnownNat m, KnownNat n) => BitVector m -> BitVector n                                                 -> BitVector (Max m n + 1)-minus# (BV a) (BV b) =+minus# (BV 0 a) (BV 0 b) =   let sz   = fromInteger (natVal (Proxy @(Max m n + 1)))       mask = 1 `shiftL` sz       z    = a - b-  in  if z < 0 then BV (mask + z) else BV z+  in  if z < 0 then BV 0 (mask + z) else BV 0 z+minus# bv1 bv2 = undefErrorP "minus" bv1 bv2  {-# NOINLINE times# #-}-times# :: BitVector m -> BitVector n -> BitVector (m + n)-times# (BV a) (BV b) = BV (a * b)+times# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (m + n)+times# (BV 0 a) (BV 0 b) = BV 0 (a * b)+times# bv1 bv2 = undefErrorP "times" bv1 bv2  instance KnownNat n => Real (BitVector n) where   toRational = toRational . toInteger#@@ -513,15 +585,18 @@   divMod  n d = (n `quot#` d,n `rem#` d)   toInteger   = toInteger# -quot#,rem# :: BitVector n -> BitVector n -> BitVector n+quot#,rem# :: KnownNat n => BitVector n -> BitVector n -> BitVector n {-# NOINLINE quot# #-}-quot# (BV i) (BV j) = BV (i `quot` j)+quot# (BV 0 i) (BV 0 j) = BV 0 (i `quot` j)+quot# bv1 bv2 = undefErrorP "quot" bv1 bv2 {-# NOINLINE rem# #-}-rem# (BV i) (BV j) = BV (i `rem` j)+rem# (BV 0 i) (BV 0 j) = BV 0 (i `rem` j)+rem# bv1 bv2 = undefErrorP "rem" bv1 bv2  {-# NOINLINE toInteger# #-}-toInteger# :: BitVector n -> Integer-toInteger# (BV i) = i+toInteger# :: KnownNat n => BitVector n -> Integer+toInteger# (BV 0 i) = i+toInteger# bv = undefErrorU "toInteger" bv  instance KnownNat n => Bits (BitVector n) where   (.&.)             = and#@@ -558,22 +633,25 @@  {-# NOINLINE reduceAnd# #-} reduceAnd# :: KnownNat n => BitVector n -> Bit-reduceAnd# bv@(BV i) = Bit (smallInteger (dataToTag# check))+reduceAnd# bv@(BV 0 i) = Bit 0 (smallInteger (dataToTag# check))   where     check = i == maxI      sz    = natVal bv     maxI  = (2 ^ sz) - 1+reduceAnd# bv = V.foldl (.&.) 1 (V.bv2v bv)  {-# NOINLINE reduceOr# #-}-reduceOr# :: BitVector n -> Bit-reduceOr# (BV i) = Bit (smallInteger (dataToTag# check))+reduceOr# :: KnownNat n => BitVector n -> Bit+reduceOr# (BV 0 i) = Bit 0 (smallInteger (dataToTag# check))   where     check = i /= 0+reduceOr# bv = V.foldl (.|.) 0 (V.bv2v bv)  {-# NOINLINE reduceXor# #-}-reduceXor# :: BitVector n -> Bit-reduceXor# (BV i) = Bit (toInteger (popCount i `mod` 2))+reduceXor# :: KnownNat n => BitVector n -> Bit+reduceXor# (BV 0 i) = Bit 0 (toInteger (popCount i `mod` 2))+reduceXor# bv = undefErrorU "reduceXor" bv  instance Default (BitVector n) where   def = minBound#@@ -591,10 +669,9 @@ -- ** Indexing {-# NOINLINE index# #-} index# :: KnownNat n => BitVector n -> Int -> Bit-index# bv@(BV v) i-    | i >= 0 && i < sz = Bit (smallInteger-                             (dataToTag#-                             (testBit v i)))+index# bv@(BV m v) i+    | i >= 0 && i < sz = Bit (smallInteger (dataToTag# (testBit m i)))+                             (smallInteger (dataToTag# (testBit v i)))     | otherwise        = err   where     sz  = fromInteger (natVal bv)@@ -608,18 +685,21 @@ {-# NOINLINE msb# #-} -- | MSB msb# :: forall n . KnownNat n => BitVector n -> Bit-msb# (BV v)+msb# (BV m v)   = let i = fromInteger (natVal (Proxy @n) - 1)-    in  Bit (smallInteger (dataToTag# (testBit v i)))+    in  Bit (smallInteger (dataToTag# (testBit m i)))+            (smallInteger (dataToTag# (testBit v i)))  {-# NOINLINE lsb# #-} -- | LSB lsb# :: BitVector n -> Bit-lsb# (BV v) = Bit (smallInteger (dataToTag# (testBit v 0)))+lsb# (BV m v) = Bit (smallInteger (dataToTag# (testBit m 0)))+                    (smallInteger (dataToTag# (testBit v 0)))  {-# NOINLINE slice# #-} slice# :: BitVector (m + 1 + i) -> SNat m -> SNat n -> BitVector (m + 1 - n)-slice# (BV i) m n = BV (shiftR (i .&. mask) n')+slice# (BV msk i) m n = BV (shiftR (msk .&. mask) n')+                           (shiftR (i   .&. mask) n')   where     m' = snatToInteger m     n' = snatToNum n@@ -632,15 +712,18 @@ {-# NOINLINE (++#) #-} -- | Concatenate two 'BitVector's (++#) :: KnownNat m => BitVector n -> BitVector m -> BitVector (n + m)-(BV v1) ++# bv2@(BV v2) = BV (v1' + v2)+(BV m1 v1) ++# bv2@(BV m2 v2) = BV (m1' .|. m2) (v1' .|. v2)   where-    v1' = shiftL v1 (fromInteger (natVal bv2))+    size2 = fromInteger (natVal bv2)+    v1' = shiftL v1 size2+    m1' = shiftL m1 size2  -- * Modifying BitVectors {-# NOINLINE replaceBit# #-} replaceBit# :: KnownNat n => BitVector n -> Int -> Bit -> BitVector n-replaceBit# bv@(BV v) i (Bit b)-    | i >= 0 && i < sz = BV (if b == 1 then setBit v i else clearBit v i)+replaceBit# bv@(BV m v) i (Bit mb b)+    | i >= 0 && i < sz = BV (clearBit m i  .|. (mb `shiftL` i))+                            (if testBit b 0 && mb == 0 then setBit v i else clearBit v i)     | otherwise        = err   where     sz   = fromInteger (natVal bv)@@ -652,74 +735,98 @@                           ]  {-# NOINLINE setSlice# #-}-setSlice# :: BitVector (m + 1 + i) -> SNat m -> SNat n -> BitVector (m + 1 - n)-          -> BitVector (m + 1 + i)-setSlice# (BV i) m n (BV j) = BV ((i .&. mask) .|. j')+setSlice#+  :: BitVector (m + 1 + i)+  -> SNat m+  -> SNat n+  -> BitVector (m + 1 - n)+  -> BitVector (m + 1 + i)+setSlice# (BV iMask i) m n (BV jMask j) = BV ((iMask .&. mask) .|. jMask')+                                             ((i     .&. mask) .|. j')   where     m' = snatToInteger m     n' = snatToInteger n -    j'   = shiftL j (fromInteger n')+    j'     = shiftL j     (fromInteger n')+    jMask' = shiftL jMask (fromInteger n')     mask = complement ((2 ^ (m' + 1) - 1) `xor` (2 ^ n' - 1))  {-# NOINLINE split# #-}-split# :: forall n m . KnownNat n-       => BitVector (m + n) -> (BitVector m, BitVector n)-split# (BV i) = (BV l, BV r)+split#+  :: forall n m+   . KnownNat n+  => BitVector (m + n)+  -> (BitVector m, BitVector n)+split# (BV m i) = (BV lMask l, BV rMask r)   where     n     = fromInteger (natVal (Proxy @n))     mask  = 1 `shiftL` n     -- The code below is faster than:     -- > (l,r) = i `divMod` mask-    r    = i `mod` mask-    l    = i `shiftR` n+    r     = i `mod` mask+    rMask = m `mod` mask+    l     = i `shiftR` n+    lMask = m `shiftR` n + and#, or#, xor# :: BitVector n -> BitVector n -> BitVector n {-# NOINLINE and# #-}-and# (BV v1) (BV v2) = BV (v1 .&. v2)+and# (BV m1 v1) (BV m2 v2) = BV mask (v1 .&. v2  .&. complement mask)+  where+    mask = (m1.&.v2 .|. m1.&.m2 .|. m2.&.v1)  {-# NOINLINE or# #-}-or# (BV v1) (BV v2) = BV (v1 .|. v2)+or# (BV m1 v1) (BV m2 v2) = BV mask ((v1.|.v2) .&. complement mask)+  where+    mask = m1 .&. complement v2  .|.  m1.&.m2  .|.  m2 .&. complement v1  {-# NOINLINE xor# #-}-xor# (BV v1) (BV v2) = BV (v1 `xor` v2)+xor# (BV m1 v1) (BV m2 v2) = BV mask ((v1 `xor` v2) .&. complement mask)+  where+    mask = m1 .|. m2 + {-# NOINLINE complement# #-} complement# :: KnownNat n => BitVector n -> BitVector n-complement# (BV v1) = fromInteger_INLINE (complement v1)+complement# (BV m v) = fromInteger_INLINE m (complement v .&. complement m)  shiftL#, shiftR#, rotateL#, rotateR#   :: KnownNat n => BitVector n -> Int -> BitVector n  {-# NOINLINE shiftL# #-}-shiftL# (BV v) i+shiftL# (BV m v) i   | i < 0     = error               $ "'shiftL undefined for negative number: " ++ show i-  | otherwise = fromInteger_INLINE (shiftL v i)+  | otherwise = fromInteger_INLINE (shiftL m i) (shiftL v i)  {-# NOINLINE shiftR# #-}-shiftR# (BV v) i+shiftR# (BV m v) i   | i < 0     = error               $ "'shiftR undefined for negative number: " ++ show i-  | otherwise = BV (shiftR v i)+  | otherwise = BV (shiftR m i) (shiftR v i)  {-# NOINLINE rotateL# #-}-rotateL# _ b | b < 0 = error "'shiftL undefined for negative numbers"-rotateL# bv@(BV n) b   = fromInteger_INLINE (l .|. r)+rotateL# _ b | b < 0   = error "'shiftL undefined for negative numbers"+rotateL# bv@(BV m v) b = fromInteger_INLINE (ml .|. mr) (vl .|. vr)   where-    l    = shiftL n b'-    r    = shiftR n b''+    vl    = shiftL v b'+    vr    = shiftR v b'' +    ml    = shiftL m b'+    mr    = shiftR m b''+     b'   = b `mod` sz     b''  = sz - b'     sz   = fromInteger (natVal bv)  {-# NOINLINE rotateR# #-}-rotateR# _ b | b < 0 = error "'shiftR undefined for negative numbers"-rotateR# bv@(BV n) b   = fromInteger_INLINE (l .|. r)+rotateR# _ b | b < 0   = error "'shiftR undefined for negative numbers"+rotateR# bv@(BV m v) b = fromInteger_INLINE (ml .|. mr) (vl .|. vr)   where-    l   = shiftR n b'-    r   = shiftL n b''+    vl   = shiftR v b'+    vr   = shiftL v b''+    ml   = shiftR m b'+    mr   = shiftL m b''      b'  = b `mod` sz     b'' = sz - b'@@ -732,51 +839,56 @@ {-# INLINE popCountBV #-}  instance Resize BitVector where-  resize     = resize#-  zeroExtend = extend+  resize     = resizeBV+  zeroExtend = (0 ++#)   signExtend = \bv -> (if msb# bv == low then id else complement) 0 ++# bv-  truncateB  = resize#+  truncateB  = truncateB# -{-# NOINLINE resize# #-}-resize# :: forall n m . KnownNat m => BitVector n -> BitVector m-resize# (BV i) = let m = 1 `shiftL` fromInteger (natVal (Proxy @m))-                 in  if i >= m then fromInteger_INLINE i else BV i+resizeBV :: forall n m . (KnownNat n, KnownNat m) => BitVector n -> BitVector m+resizeBV = case compareSNat @n @m (SNat @n) (SNat @m) of+  SNatLE -> (++#) @n @(m-n) 0+  SNatGT -> truncateB# @m @(n - m)+{-# INLINE resizeBV #-} +truncateB# :: forall a b . KnownNat a => BitVector (a + b) -> BitVector a+truncateB# (BV msk i) = fromInteger_INLINE msk i+{-# NOINLINE truncateB# #-}+ instance KnownNat n => Lift (BitVector n) where-  lift bv@(BV i) = sigE [| fromInteger# i |] (decBitVector (natVal bv))+  lift bv@(BV m i) = sigE [| fromInteger# m i |] (decBitVector (natVal bv))   {-# NOINLINE lift #-}  decBitVector :: Integer -> TypeQ decBitVector n = appT (conT ''BitVector) (litT $ numTyLit n)  instance KnownNat n => SaturatingNum (BitVector n) where-  satPlus SatWrap a b = a +# b-  satPlus SatZero a b =+  satAdd SatWrap a b = a +# b+  satAdd SatZero a b =     let r = plus# a b     in  if msb# r == low-           then resize# r+           then truncateB# r            else minBound#-  satPlus _ a b =+  satAdd _ a b =     let r  = plus# a b     in  if msb# r == low-           then resize# r+           then truncateB# r            else maxBound# -  satMin SatWrap a b = a -# b-  satMin _ a b =+  satSub SatWrap a b = a -# b+  satSub _ a b =     let r = minus# a b     in  if msb# r == low-           then resize# r+           then truncateB# r            else minBound# -  satMult SatWrap a b = a *# b-  satMult SatZero a b =+  satMul SatWrap a b = a *# b+  satMul SatZero a b =     let r       = times# a b         (rL,rR) = split# r     in  case rL of           0 -> rR           _ -> minBound#-  satMult _ a b =+  satMul _ a b =     let r       = times# a b         (rL,rR) = split# r     in  case rL of@@ -806,3 +918,117 @@ type instance IxValue (BitVector n) = Bit instance KnownNat n => Ixed (BitVector n) where   ix i f bv = replaceBit# bv i <$> f (index# bv i)+++-- error for infix operator+undefErrorI :: (HasCallStack, KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a+undefErrorI op bv1 bv2 = withFrozenCallStack $+  errorX $ "Clash.Sized.BitVector." ++ op+  ++ " called with (partially) undefined arguments: "+  ++ show bv1 ++ " " ++ op ++" " ++ show bv2++-- error for prefix operator/function+undefErrorP :: (HasCallStack, KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a+undefErrorP op bv1 bv2 = withFrozenCallStack $+  errorX $ "Clash.Sized.BitVector." ++ op+  ++ " called with (partially) undefined arguments: "+  ++ show bv1 ++ " " ++ show bv2++-- error for prefix operator/function+undefErrorP3 :: (HasCallStack, KnownNat m, KnownNat n, KnownNat o) => String -> BitVector m -> BitVector n -> BitVector o -> a+undefErrorP3 op bv1 bv2 bv3 = withFrozenCallStack $+  errorX $ "Clash.Sized.BitVector." ++ op+  ++ " called with (partially) undefined arguments: "+  ++ show bv1 ++ " " ++ show bv2 ++ " " ++ show bv3++-- error for unary operator/function+undefErrorU :: (HasCallStack, KnownNat n) => String -> BitVector n -> a+-- undefErrorU op bv1 = undefError ("Clash.Sized.BitVector." ++ op) [bv1]+undefErrorU op bv1 = withFrozenCallStack $+  errorX $ "Clash.Sized.BitVector." ++ op+  ++ " called with (partially) undefined argument: "+  ++ show bv1++undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a+undefError op bvs = withFrozenCallStack $+  errorX $ op+  ++ " called with (partially) undefined arguments: "+  ++ unwords (L.map show bvs)+++-- | Implement BitVector undefinedness checking for unpack funtions+checkUnpackUndef :: (KnownNat n, Typeable a)+                 => (BitVector n -> a) -- ^ unpack function+                 -> BitVector n -> a+checkUnpackUndef f bv@(BV 0 _) = f bv+checkUnpackUndef _ bv = res+  where+    ty = typeOf res+    res = undefError (show ty ++ ".unpack") [bv]+{-# NOINLINE checkUnpackUndef #-}++-- | Create a BitVector with all its bits undefined+undefined# :: forall n . KnownNat n => BitVector n+undefined# =+  let m = 1 `shiftL` fromInteger (natVal (Proxy @n))+  in  BV (m-1) 0+{-# NOINLINE undefined# #-}++-- | Check if one BitVector is like another.+-- NFDataX bits in the second argument are interpreted as don't care bits.+--+-- >>> let expected = $$(bLit "1.") :: BitVector 2+-- >>> let checked  = $$(bLit "11") :: BitVector 2+-- >>> checked  `isLike` expected+-- True+-- >>> expected `isLike` checked+-- False+--+-- __NB__: Not synthesizable+isLike :: BitVector n -> BitVector n -> Bool+isLike (BV cMask c) (BV eMask e) = e' == c' && e' == c''+  where+    -- | set don't care bits to 0+    e' = e .&. complement eMask++    -- | checked with undefined bits set to 0+    c' = (c .&. complement cMask) .&. complement eMask+    -- | checked with undefined bits set to 1+    c'' = (c .|. cMask) .&. complement eMask+{-# NOINLINE isLike #-}++fromBits :: [Bit] -> Integer+fromBits = L.foldl (\v b -> v `shiftL` 1 .|. fromIntegral b) 0++-- | Template Haskell macro for generating a pattern matching on some+-- bits of a value.+--+-- This macro compiles to an efficient view pattern that matches the+-- bits of a given value against the bits specified in the+-- pattern. The scrutinee can be any type that is an instance of the+-- 'Num', 'Bits' and 'Eq' typeclasses.+--+-- The bit pattern is specified by a string which contains @\'0\'@ or+-- @\'1\'@ for matching a bit, or @\'.\'@ for bits which are not matched.+--+-- The following example matches a byte against two bit patterns where+-- some bits are relevant and others are not:+--+-- @+--   decode :: Unsigned 8 -> Maybe Bool+--   decode $(bitPattern "00...110") = Just True+--   decode $(bitPattern "10..0001") = Just False+--   decode _ = Nothing+-- @+bitPattern :: String -> Q Pat+bitPattern s = [p| (($mask .&.) -> $target) |]+  where+    bs = parse <$> s++    mask = litE . IntegerL . fromBits $ maybe 0 (const 1) <$> bs+    target = litP . IntegerL . fromBits $ fromMaybe 0 <$> bs++    parse '.' = Nothing+    parse '0' = Just 0+    parse '1' = Just 1+    parse c = error $ "Invalid bit pattern: " ++ show c
src/Clash/Sized/Internal/BitVector.hs-boot view
@@ -9,8 +9,11 @@ {-# LANGUAGE RoleAnnotations #-} module Clash.Sized.Internal.BitVector where -import GHC.TypeLits (Nat)+import GHC.TypeLits (KnownNat,Nat)+import GHC.Stack    (HasCallStack)  type role BitVector phantom data BitVector :: Nat -> * data Bit++undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a
src/Clash/Sized/Internal/Index.hs view
@@ -1,12 +1,17 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2016     , Myrtle Software Ltd+                  2016-2019, Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} +{-# LANGUAGE BangPatterns          #-}+{-# LANGUAGE CPP                   #-} {-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveAnyClass        #-} {-# LANGUAGE DeriveDataTypeable    #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleContexts      #-} {-# LANGUAGE KindSignatures        #-} {-# LANGUAGE MagicHash             #-} {-# LANGUAGE ScopedTypeVariables   #-}@@ -16,6 +21,9 @@ {-# LANGUAGE TypeFamilies          #-} {-# LANGUAGE TypeOperators         #-} {-# LANGUAGE UndecidableInstances  #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  {-# LANGUAGE Unsafe #-} @@ -29,8 +37,11 @@     Index (..)     -- * Construction   , fromSNat+  -- * Accessors+  -- ** Length information+  , size#     -- * Type classes-    -- ** BitConvert+    -- ** BitPack   , pack#   , unpack#     -- ** Eq@@ -41,7 +52,7 @@   , ge#   , gt#   , le#-    -- ** Enum (not synthesisable)+    -- ** Enum (not synthesizable)   , enumFrom#   , enumFromThen#   , enumFromTo#@@ -67,12 +78,16 @@ where  import Control.DeepSeq            (NFData (..))+import Data.Bits                  (Bits (..), FiniteBits (..)) import Data.Data                  (Data)-import Data.Default               (Default (..))+import Data.Default.Class         (Default (..)) import Data.Proxy                 (Proxy (..)) import Text.Read                  (Read (..), ReadPrec) import Language.Haskell.TH        (TypeQ, appT, conT, litT, numTyLit, sigE) import Language.Haskell.TH.Syntax (Lift(..))+import Numeric.Natural            (Natural)+import GHC.Generics               (Generic)+import GHC.Stack                  (HasCallStack) import GHC.TypeLits               (CmpNat, KnownNat, Nat, type (+), type (-),                                    type (*), type (<=), natVal) import GHC.TypeLits.Extra         (CLog)@@ -80,13 +95,16 @@                                    arbitraryBoundedIntegral,                                    coarbitraryIntegral, shrinkIntegral) -import Clash.Class.BitPack        (BitPack (..))+import Clash.Class.BitPack        (BitPack (..), packXWith) import Clash.Class.Num            (ExtendingNum (..), SaturatingNum (..),                                    SaturationMode (..)) import Clash.Class.Resize         (Resize (..))-import {-# SOURCE #-} Clash.Sized.Internal.BitVector (BitVector (BV))-import Clash.Promoted.Nat         (SNat, snatToNum, leToPlusKN)-import Clash.XException           (ShowX (..), showsPrecXWith)+import Clash.Prelude.BitIndex     (replaceBit)+import {-# SOURCE #-} Clash.Sized.Internal.BitVector (BitVector (BV), high, low, undefError)+import qualified Clash.Sized.Internal.BitVector as BV+import Clash.Promoted.Nat         (SNat(..), snatToNum, leToPlusKN)+import Clash.XException+  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)  -- | Arbitrary-bounded unsigned integer represented by @ceil(log_2(n))@ bits. --@@ -101,31 +119,35 @@ -- >>> 1 + 2 :: Index 8 -- 3 -- >>> 2 + 6 :: Index 8--- *** Exception: Clash.Sized.Index: result 8 is out of bounds: [0..7]+-- *** Exception: X: Clash.Sized.Index: result 8 is out of bounds: [0..7] -- ... -- >>> 1 - 3 :: Index 8--- *** Exception: Clash.Sized.Index: result -2 is out of bounds: [0..7]+-- *** Exception: X: Clash.Sized.Index: result -2 is out of bounds: [0..7] -- ... -- >>> 2 * 3 :: Index 8 -- 6 -- >>> 2 * 4 :: Index 8--- *** Exception: Clash.Sized.Index: result 8 is out of bounds: [0..7]+-- *** Exception: X: Clash.Sized.Index: result 8 is out of bounds: [0..7] -- ... newtype Index (n :: Nat) =     -- | The constructor, 'I', and the field, 'unsafeToInteger', are not-    -- synthesisable.+    -- synthesizable.     I { unsafeToInteger :: Integer }-  deriving Data+  deriving (Data, Generic) +{-# NOINLINE size# #-}+size# :: (KnownNat n, 1 <= n) => Index n -> Int+size# = BV.size# . pack#+ instance NFData (Index n) where   rnf (I i) = rnf i `seq` ()   {-# NOINLINE rnf #-}   -- NOINLINE is needed so that Clash doesn't trip on the "Index ~# Integer"   -- coercion -instance KnownNat n => BitPack (Index n) where+instance (KnownNat n, 1 <= n) => BitPack (Index n) where   type BitSize (Index n) = CLog 2 n-  pack   = pack#+  pack   = packXWith pack#   unpack = unpack#  -- | Safely convert an `SNat` value to an `Index`@@ -134,11 +156,12 @@  {-# NOINLINE pack# #-} pack# :: Index n -> BitVector (CLog 2 n)-pack# (I i) = BV i+pack# (I i) = BV 0 i  {-# NOINLINE unpack# #-}-unpack# :: KnownNat n => BitVector (CLog 2 n) -> Index n-unpack# (BV i) = fromInteger_INLINE i+unpack# :: (KnownNat n, 1 <= n) => BitVector (CLog 2 n) -> Index n+unpack# (BV 0 i) = fromInteger_INLINE i+unpack# bv = undefError "Index.unpack" [bv]  instance Eq (Index n) where   (==) = eq#@@ -169,7 +192,7 @@ le# (I n) (I m) = n <= m  -- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and--- 'enumFromThenTo', are not synthesisable.+-- 'enumFromThenTo', are not synthesizable. instance KnownNat n => Enum (Index n) where   succ           = (+# fromInteger# 1)   pred           = (-# fromInteger# 1)@@ -225,19 +248,19 @@ {-# NOINLINE fromInteger# #-} fromInteger# = fromInteger_INLINE {-# INLINE fromInteger_INLINE #-}-fromInteger_INLINE :: forall n . KnownNat n => Integer -> Index n+fromInteger_INLINE :: forall n . (HasCallStack, KnownNat n) => Integer -> Index n fromInteger_INLINE i = bound `seq` if i > (-1) && i < bound then I i else err   where     bound = natVal (Proxy @n)-    err   = error ("Clash.Sized.Index: result " ++ show i +++    err   = errorX ("Clash.Sized.Index: result " ++ show i ++                    " is out of bounds: [0.." ++ show (bound - 1) ++ "]")  instance ExtendingNum (Index m) (Index n) where   type AResult (Index m) (Index n) = Index (m + n - 1)-  plus  = plus#-  minus = minus#+  add  = plus#+  sub = minus#   type MResult (Index m) (Index n) = Index (((m - 1) * (n - 1)) + 1)-  times = times#+  mul = times#  plus#, minus# :: Index m -> Index n -> Index (m + n - 1) {-# NOINLINE plus# #-}@@ -256,58 +279,55 @@ times# (I a) (I b) = I (a * b)  instance (KnownNat n, 1 <= n) => SaturatingNum (Index n) where-  satPlus SatWrap a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case plus# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> resize# (z - m)-        z -> resize# z-  satPlus SatZero a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case plus# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> fromInteger# 0+  satAdd SatWrap !a !b =+    case snatToNum @Int (SNat @n) of+      1 -> fromInteger# 0+      _ -> leToPlusKN @1 @n $+        case plus# a b of+          z | let m = fromInteger# (natVal (Proxy @ n))+            , z >= m -> resize# (z - m)+          z -> resize# z+  satAdd SatZero a b =+    leToPlusKN @1 @n $+      case plus# a b of+        z | let m = fromInteger# (natVal (Proxy @ (n - 1)))+          , z > m -> fromInteger# 0         z -> resize# z-  satPlus _ a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case plus# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> maxBound#+  satAdd _ a b =+    leToPlusKN @1 @n $+      case plus# a b of+        z | let m = fromInteger# (natVal (Proxy @ (n - 1)))+          , z > m -> maxBound#         z -> resize# z -  satMin SatWrap a b =+  satSub SatWrap a b =     if lt# a b        then maxBound -# (b -# a) +# 1        else a -# b -  satMin _ a b =+  satSub _ a b =     if lt# a b        then fromInteger# 0        else a -# b -  satMult SatWrap a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case times# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> resize# (z - m)-        z -> resize# z-  satMult SatZero a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case times# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> fromInteger# 0+  satMul SatWrap !a !b =+    case snatToNum @Int (SNat @n) of+      1 -> fromInteger# 0+      _ -> leToPlusKN @1 @n $+        case times# a b of+          z -> let m = fromInteger# (natVal (Proxy @ n))+               in resize# (z `mod` m)+  satMul SatZero a b =+    leToPlusKN @1 @n $+      case times# a b of+        z | let m = fromInteger# (natVal (Proxy @ (n - 1)))+          , z > m -> fromInteger# 0         z -> resize# z-  satMult _ a b =-    leToPlusKN @1 a $ \a' ->-    leToPlusKN @1 b $ \b' ->-      case times# a' b' of-        z | let m = fromInteger# (natVal (Proxy @ n))-          , z >= m -> maxBound#+  satMul _ a b =+    leToPlusKN @1 @n $+      case times# a b of+        z | let m = fromInteger# (natVal (Proxy @ (n - 1)))+          , z > m -> maxBound#         z -> resize# z  instance KnownNat n => Real (Index n) where@@ -332,6 +352,31 @@ toInteger# :: Index n -> Integer toInteger# (I n) = n +instance (KnownNat n, 1 <= n) => Bits (Index n) where+  a .&. b           = unpack# $ BV.and# (pack# a) (pack# b)+  a .|. b           = unpack# $ BV.or# (pack# a) (pack# b)+  xor a b           = unpack# $ BV.xor# (pack# a) (pack# b)+  complement        = unpack# . BV.complement# . pack#+  zeroBits          = unpack# zeroBits+  bit i             = unpack# $ bit i+  setBit v i        = unpack# $ replaceBit i high (pack# v)+  clearBit v i      = unpack# $ replaceBit i low  (pack# v)+  complementBit v i = unpack# $ complementBit (pack# v) i+  testBit v i       = testBit (pack# v) i+  bitSizeMaybe v    = Just (size# v)+  bitSize           = size#+  isSigned _        = False+  shiftL v i        = unpack# $ shiftL (pack# v) i+  shiftR v i        = unpack# $ shiftR (pack# v) i+  rotateL v i       = unpack# $ rotateL (pack# v) i+  rotateR v i       = unpack# $ rotateR (pack# v) i+  popCount i        = popCount (pack# i)++instance (KnownNat n, 1 <= n) => FiniteBits (Index n) where+  finiteBitSize        = size#+  countLeadingZeros  i = countLeadingZeros  (pack# i)+  countTrailingZeros i = countTrailingZeros (pack# i)+ instance Resize Index where   resize     = resize#   zeroExtend = extend@@ -355,9 +400,13 @@ instance ShowX (Index n) where   showsPrecX = showsPrecXWith showsPrec --- | None of the 'Read' class' methods are synthesisable.+instance NFDataX (Index n) where+  deepErrorX = errorX+  rnfX = rwhnfX++-- | None of the 'Read' class' methods are synthesizable. instance KnownNat n => Read (Index n) where-  readPrec = fromIntegral <$> (readPrec :: ReadPrec Word)+  readPrec = fromIntegral <$> (readPrec :: ReadPrec Natural)  instance KnownNat n => Default (Index n) where   def = fromInteger# 0
src/Clash/Sized/Internal/Signed.hs view
@@ -6,8 +6,9 @@ -}  {-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveAnyClass             #-}+{-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE DeriveDataTypeable         #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures             #-} {-# LANGUAGE MagicHash                  #-} {-# LANGUAGE MultiParamTypeClasses      #-}@@ -31,10 +32,10 @@     -- ** Length information   , size#     -- * Type classes-    -- ** BitConvert+    -- ** BitPack   , pack#   , unpack#-    -- Eq+    -- ** Eq   , eq#   , neq#     -- ** Ord@@ -42,7 +43,7 @@   , ge#   , gt#   , le#-    -- ** Enum (not synthesisable)+    -- ** Enum (not synthesizable)   , enumFrom#   , enumFromThen#   , enumFromTo#@@ -88,9 +89,10 @@ import Control.Lens                   (Index, Ixed (..), IxValue) import Data.Bits                      (Bits (..), FiniteBits (..)) import Data.Data                      (Data)-import Data.Default                   (Default (..))+import Data.Default.Class             (Default (..)) import Data.Proxy                     (Proxy (..)) import Text.Read                      (Read (..), ReadPrec)+import GHC.Generics                   (Generic) import GHC.TypeLits                   (KnownNat, Nat, type (+), natVal) import GHC.TypeLits.Extra             (Max) import Language.Haskell.TH            (TypeQ, appT, conT, litT, numTyLit, sigE)@@ -99,15 +101,16 @@                                        arbitraryBoundedIntegral,                                        coarbitraryIntegral, shrinkIntegral) -import Clash.Class.BitPack            (BitPack (..))+import Clash.Class.BitPack            (BitPack (..), packXWith) import Clash.Class.Num                (ExtendingNum (..), SaturatingNum (..),                                        SaturationMode (..)) import Clash.Class.Resize             (Resize (..)) import Clash.Prelude.BitIndex         ((!), msb, replaceBit, split) import Clash.Prelude.BitReduction     (reduceAnd, reduceOr)-import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, (++#), high, low)+import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, (++#), high, low, undefError) import qualified Clash.Sized.Internal.BitVector as BV-import Clash.XException               (ShowX (..), showsPrecXWith)+import Clash.XException+  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)  -- | Arbitrary-width signed integer represented by @n@ bits, including the sign -- bit.@@ -134,22 +137,26 @@ -- 6 -- >>> 2 * 4 :: Signed 4 -- -8--- >>> (2 :: Signed 3) `times` (4 :: Signed 4) :: Signed 7+-- >>> (2 :: Signed 3) `mul` (4 :: Signed 4) :: Signed 7 -- 8--- >>> (2 :: Signed 3) `plus` (3 :: Signed 3) :: Signed 4+-- >>> (2 :: Signed 3) `add` (3 :: Signed 3) :: Signed 4 -- 5--- >>> (-2 :: Signed 3) `plus` (-3 :: Signed 3) :: Signed 4+-- >>> (-2 :: Signed 3) `add` (-3 :: Signed 3) :: Signed 4 -- -5--- >>> satPlus SatSymmetric 2 3 :: Signed 3+-- >>> satAdd SatSymmetric 2 3 :: Signed 3 -- 3--- >>> satPlus SatSymmetric (-2) (-3) :: Signed 3+-- >>> satAdd SatSymmetric (-2) (-3) :: Signed 3 -- -3 newtype Signed (n :: Nat) =     -- | The constructor, 'S', and the field, 'unsafeToInteger', are not-    -- synthesisable.+    -- synthesizable.     S { unsafeToInteger :: Integer}-  deriving (Data)+  deriving (Data, Generic) +instance NFDataX (Signed n) where+  deepErrorX = errorX+  rnfX = rwhnfX+ {-# NOINLINE size# #-} size# :: KnownNat n => Signed n -> Int size# bv = fromInteger (natVal bv)@@ -167,25 +174,26 @@ instance ShowX (Signed n) where   showsPrecX = showsPrecXWith showsPrec --- | None of the 'Read' class' methods are synthesisable.+-- | None of the 'Read' class' methods are synthesizable. instance KnownNat n => Read (Signed n) where-  readPrec = fromIntegral <$> (readPrec :: ReadPrec Int)+  readPrec = fromIntegral <$> (readPrec :: ReadPrec Integer)  instance KnownNat n => BitPack (Signed n) where   type BitSize (Signed n) = n-  pack   = pack#+  pack   = packXWith pack#   unpack = unpack#  {-# NOINLINE pack# #-} pack# :: forall n . KnownNat n => Signed n -> BitVector n pack# (S i) = let m = 1 `shiftL` fromInteger (natVal (Proxy @n))-              in  if i < 0 then BV (m + i) else BV i+              in  if i < 0 then BV 0 (m + i) else BV 0 i  {-# NOINLINE unpack# #-} unpack# :: forall n . KnownNat n => BitVector n -> Signed n-unpack# (BV i) =+unpack# (BV 0 i) =   let m = 1 `shiftL` fromInteger (natVal (Proxy @n) - 1)   in  if i >= m then S (i-2*m) else S i+unpack# bv = undefError "Signed.unpack" [bv]  instance Eq (Signed n) where   (==) = eq#@@ -216,7 +224,7 @@ le# (S n) (S m) = n <= m  -- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and--- 'enumFromThenTo', are not synthesisable.+-- 'enumFromThenTo', are not synthesizable. instance KnownNat n => Enum (Signed n) where   succ           = (+# fromInteger# 1)   pred           = (-# fromInteger# 1)@@ -295,7 +303,7 @@  {-# INLINE fromInteger_INLINE #-} fromInteger_INLINE :: forall n . KnownNat n => Integer -> Signed n-fromInteger_INLINE i = mask `seq` S res+fromInteger_INLINE i = if mask == 0 then S 0 else S res   where     mask = 1 `shiftL` fromInteger (natVal (Proxy @n) -1)     res  = case divMod i mask of@@ -304,10 +312,10 @@  instance ExtendingNum (Signed m) (Signed n) where   type AResult (Signed m) (Signed n) = Signed (Max m n + 1)-  plus  = plus#-  minus = minus#+  add  = plus#+  sub = minus#   type MResult (Signed m) (Signed n) = Signed (m + n)-  times = times#+  mul = times#  plus#, minus# :: Signed m -> Signed n -> Signed (Max m n + 1) {-# NOINLINE plus# #-}@@ -452,8 +460,8 @@ decSigned n = appT (conT ''Signed) (litT $ numTyLit n)  instance KnownNat n => SaturatingNum (Signed n) where-  satPlus SatWrap  a b = a +# b-  satPlus SatBound a b =+  satAdd SatWrap  a b = a +# b+  satAdd SatBound a b =     let r      = plus# a b         (_,r') = split r     in  case msb r `xor` msb r' of@@ -461,13 +469,13 @@           _ -> case msb a .&. msb b of             0 -> maxBound#             _ -> minBound#-  satPlus SatZero a b =+  satAdd SatZero a b =     let r      = plus# a b         (_,r') = split r     in  case msb r `xor` msb r' of           0 -> unpack# r'           _ -> fromInteger# 0-  satPlus SatSymmetric a b =+  satAdd SatSymmetric a b =     let r      = plus# a b         (_,r') = split r     in  case msb r `xor` msb r' of@@ -476,8 +484,8 @@             0 -> maxBound#             _ -> minBoundSym# -  satMin SatWrap a b = a -# b-  satMin SatBound a b =+  satSub SatWrap a b = a -# b+  satSub SatBound a b =     let r      = minus# a b         (_,r') = split r     in  case msb r `xor` msb r' of@@ -485,13 +493,13 @@           _ -> case BV.pack# (msb a) ++# BV.pack# (msb b) of             2 -> minBound#             _ -> maxBound#-  satMin SatZero a b =+  satSub SatZero a b =     let r      = minus# a b         (_,r') = split r     in  case msb r `xor` msb r' of           0 -> unpack# r'           _ -> fromInteger# 0-  satMin SatSymmetric a b =+  satSub SatSymmetric a b =     let r      = minus# a b         (_,r') = split r     in  case msb r `xor` msb r' of@@ -500,8 +508,8 @@             2 -> minBoundSym#             _ -> maxBound# -  satMult SatWrap a b = a *# b-  satMult SatBound a b =+  satMul SatWrap a b = a *# b+  satMul SatBound a b =     let r        = times# a b         (rL,rR)  = split r         overflow = complement (reduceOr (BV.pack# (msb rR) ++# pack rL)) .|.@@ -511,7 +519,7 @@           _ -> case msb rL of             0 -> maxBound#             _ -> minBound#-  satMult SatZero a b =+  satMul SatZero a b =     let r        = times# a b         (rL,rR)  = split r         overflow = complement (reduceOr (BV.pack# (msb rR) ++# pack rL)) .|.@@ -519,7 +527,7 @@     in  case overflow of           1 -> unpack# rR           _ -> fromInteger# 0-  satMult SatSymmetric a b =+  satMul SatSymmetric a b =     let r        = times# a b         (rL,rR)  = split r         overflow = complement (reduceOr (BV.pack# (msb rR) ++# pack rL)) .|.
src/Clash/Sized/Internal/Unsigned.hs view
@@ -6,7 +6,9 @@ -}  {-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DeriveAnyClass             #-} {-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE MagicHash                  #-} {-# LANGUAGE MultiParamTypeClasses      #-} {-# LANGUAGE ScopedTypeVariables        #-}@@ -28,7 +30,7 @@     -- ** Length information   , size#     -- * Type classes-    -- ** BitConvert+    -- ** BitPack   , pack#   , unpack#     -- ** Eq@@ -39,7 +41,7 @@   , ge#   , gt#   , le#-    -- ** Enum (not synthesisable)+    -- ** Enum (not synthesizable)   , enumFrom#   , enumFromThen#   , enumFromTo#@@ -79,26 +81,29 @@ import Control.Lens                   (Index, Ixed (..), IxValue) import Data.Bits                      (Bits (..), FiniteBits (..)) import Data.Data                      (Data)-import Data.Default                   (Default (..))+import Data.Default.Class             (Default (..)) import Data.Proxy                     (Proxy (..)) import Text.Read                      (Read (..), ReadPrec)+import GHC.Generics                   (Generic) import GHC.TypeLits                   (KnownNat, Nat, type (+), natVal) import GHC.TypeLits.Extra             (Max) import Language.Haskell.TH            (TypeQ, appT, conT, litT, numTyLit, sigE) import Language.Haskell.TH.Syntax     (Lift(..))+import Numeric.Natural                (Natural) import Test.QuickCheck.Arbitrary      (Arbitrary (..), CoArbitrary (..),                                        arbitraryBoundedIntegral,                                        coarbitraryIntegral) -import Clash.Class.BitPack            (BitPack (..))+import Clash.Class.BitPack            (BitPack (..), packXWith) import Clash.Class.Num                (ExtendingNum (..), SaturatingNum (..),                                        SaturationMode (..)) import Clash.Class.Resize             (Resize (..)) import Clash.Prelude.BitIndex         ((!), msb, replaceBit, split) import Clash.Prelude.BitReduction     (reduceOr)-import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, high, low)+import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, high, low, undefError) import qualified Clash.Sized.Internal.BitVector as BV-import Clash.XException               (ShowX (..), showsPrecXWith)+import Clash.XException+  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)  -- | Arbitrary-width unsigned integer represented by @n@ bits --@@ -123,19 +128,19 @@ -- 6 -- >>> 2 * 4 :: Unsigned 3 -- 0--- >>> (2 :: Unsigned 3) `times` (4 :: Unsigned 3) :: Unsigned 6+-- >>> (2 :: Unsigned 3) `mul` (4 :: Unsigned 3) :: Unsigned 6 -- 8--- >>> (2 :: Unsigned 3) `plus` (6 :: Unsigned 3) :: Unsigned 4+-- >>> (2 :: Unsigned 3) `add` (6 :: Unsigned 3) :: Unsigned 4 -- 8--- >>> satPlus SatSymmetric 2 6 :: Unsigned 3+-- >>> satAdd SatSymmetric 2 6 :: Unsigned 3 -- 7--- >>> satMin SatSymmetric 2 3 :: Unsigned 3+-- >>> satSub SatSymmetric 2 3 :: Unsigned 3 -- 0 newtype Unsigned (n :: Nat) =     -- | The constructor, 'U', and the field, 'unsafeToInteger', are not-    -- synthesisable.+    -- synthesizable.     U { unsafeToInteger :: Integer }-  deriving Data+  deriving (Data, Generic)  {-# NOINLINE size# #-} size# :: KnownNat n => Unsigned n -> Int@@ -154,22 +159,27 @@ instance ShowX (Unsigned n) where   showsPrecX = showsPrecXWith showsPrec --- | None of the 'Read' class' methods are synthesisable.+instance NFDataX (Unsigned n) where+  deepErrorX = errorX+  rnfX = rwhnfX++-- | None of the 'Read' class' methods are synthesizable. instance KnownNat n => Read (Unsigned n) where-  readPrec = fromIntegral <$> (readPrec :: ReadPrec Word)+  readPrec = fromIntegral <$> (readPrec :: ReadPrec Natural) -instance BitPack (Unsigned n) where+instance KnownNat n => BitPack (Unsigned n) where   type BitSize (Unsigned n) = n-  pack   = pack#+  pack   = packXWith pack#   unpack = unpack#  {-# NOINLINE pack# #-} pack# :: Unsigned n -> BitVector n-pack# (U i) = BV i+pack# (U i) = BV 0 i  {-# NOINLINE unpack# #-}-unpack# :: BitVector n -> Unsigned n-unpack# (BV i) = U i+unpack# :: KnownNat n => BitVector n -> Unsigned n+unpack# (BV 0 i) = U i+unpack# bv = undefError "Unsigned.unpack" [bv]  instance Eq (Unsigned n) where   (==) = eq#@@ -200,7 +210,7 @@ le# (U n) (U m) = n <= m  -- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and--- 'enumFromThenTo', are not synthesisable.+-- 'enumFromThenTo', are not synthesizable. instance KnownNat n => Enum (Unsigned n) where   succ           = (+# fromInteger# 1)   pred           = (-# fromInteger# 1)@@ -279,10 +289,10 @@  instance (KnownNat m, KnownNat n) => ExtendingNum (Unsigned m) (Unsigned n) where   type AResult (Unsigned m) (Unsigned n) = Unsigned (Max m n + 1)-  plus  = plus#-  minus = minus#+  add  = plus#+  sub = minus#   type MResult (Unsigned m) (Unsigned n) = Unsigned (m + n)-  times = times#+  mul = times#  {-# NOINLINE plus# #-} plus# :: Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)@@ -423,33 +433,33 @@ decUnsigned n = appT (conT ''Unsigned) (litT $ numTyLit n)  instance KnownNat n => SaturatingNum (Unsigned n) where-  satPlus SatWrap a b = a +# b-  satPlus SatZero a b =+  satAdd SatWrap a b = a +# b+  satAdd SatZero a b =     let r = plus# a b     in  case msb r of           0 -> resize# r           _ -> minBound#-  satPlus _ a b =+  satAdd _ a b =     let r  = plus# a b     in  case msb r of           0 -> resize# r           _ -> maxBound# -  satMin SatWrap a b = a -# b-  satMin _ a b =+  satSub SatWrap a b = a -# b+  satSub _ a b =     let r = minus# a b     in  case msb r of           0 -> resize# r           _ -> minBound# -  satMult SatWrap a b = a *# b-  satMult SatZero a b =+  satMul SatWrap a b = a *# b+  satMul SatZero a b =     let r       = times# a b         (rL,rR) = split r     in  case rL of           0 -> unpack# rR           _ -> minBound#-  satMult _ a b =+  satMul _ a b =     let r       = times# a b         (rL,rR) = split r     in  case rL of
src/Clash/Sized/RTree.hs view
@@ -4,6 +4,7 @@ Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -} +{-# LANGUAGE CPP                  #-} {-# LANGUAGE DataKinds            #-} {-# LANGUAGE GADTs                #-} {-# LANGUAGE InstanceSigs         #-}@@ -18,6 +19,9 @@ {-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns         #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  {-# LANGUAGE Trustworthy #-} @@ -56,24 +60,27 @@ where  import Control.Applicative         (liftA2)+import Control.DeepSeq             (NFData(..)) import qualified Control.Lens      as Lens-import Data.Default                (Default (..))+import Data.Default.Class          (Default (..))+import Data.Either                 (isLeft) import Data.Foldable               (toList)+import Data.Kind                   (Type) import Data.Singletons.Prelude     (Apply, TyFun, type (@@)) import Data.Proxy                  (Proxy (..)) import GHC.TypeLits                (KnownNat, Nat, type (+), type (^), type (*)) import Language.Haskell.TH.Syntax  (Lift(..))-import qualified Prelude           as P import Prelude                     hiding ((++), (!!)) import Test.QuickCheck             (Arbitrary (..), CoArbitrary (..)) -import Clash.Class.BitPack         (BitPack (..))+import Clash.Class.BitPack         (BitPack (..), packXWith) import Clash.Promoted.Nat          (SNat (..), UNat (..), pow2SNat, snatToNum,                                     subSNat, toUNat) import Clash.Promoted.Nat.Literals (d1) import Clash.Sized.Index           (Index) import Clash.Sized.Vector          (Vec (..), (!!), (++), dtfold, replace)-import Clash.XException            (ShowX (..), showsX, showsPrecXWith)+import Clash.XException+  (ShowX (..), NFDataX (..), isX, showsX, showsPrecXWith)  {- $setup >>> :set -XDataKinds@@ -91,7 +98,7 @@ let populationCount' :: (KnownNat k, KnownNat (2^k)) => BitVector (2^k) -> Index ((2^k)+1)     populationCount' bv = tdfold (Proxy @IIndex)                                  fromIntegral-                                 (\_ x y -> plus x y)+                                 (\_ x y -> add x y)                                  (v2t (bv2v bv)) :} -}@@ -100,16 +107,22 @@ -- -- * Only has elements at the leaf of the tree -- * A tree of depth /d/ has /2^d/ elements.-data RTree :: Nat -> * -> * where+data RTree :: Nat -> Type -> Type where   LR_ :: a -> RTree 0 a   BR_ :: RTree d a -> RTree d a -> RTree (d+1) a +instance NFData a => NFData (RTree d a) where+    rnf (LR_ x) = rnf x+    rnf (BR_ l r ) = rnf l `seq` rnf r+ textract :: RTree 0 a -> a-textract (LR_ x) = x+textract (LR_ x)   = x+textract (BR_ _ _) = error $ "textract: nodes hold no values" {-# NOINLINE textract #-}  tsplit :: RTree (d+1) a -> (RTree d a,RTree d a) tsplit (BR_ l r) = (l,r)+tsplit (LR_ _)   = error $ "tsplit: leaf is atomic" {-# NOINLINE tsplit #-}  -- | Leaf of a perfect depth tree@@ -179,7 +192,7 @@ instance KnownNat d => Foldable (RTree d) where   foldMap f = tfold f mappend -data TraversableTree (g :: * -> *) (a :: *) (f :: TyFun Nat *) :: *+data TraversableTree (g :: Type -> Type) (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (TraversableTree f a) d = f (RTree d a)  instance KnownNat d => Traversable (RTree d) where@@ -191,7 +204,7 @@ instance (KnownNat d, KnownNat (BitSize a), BitPack a) =>   BitPack (RTree d a) where   type BitSize (RTree d a) = (2^d) * (BitSize a)-  pack   = pack . t2v+  pack   = packXWith (pack . t2v)   unpack = v2t . unpack  type instance Lens.Index   (RTree d a) = Int@@ -213,6 +226,16 @@ instance (KnownNat d, CoArbitrary a) => CoArbitrary (RTree d a) where   coarbitrary = coarbitrary . toList +instance (KnownNat d, NFDataX a) => NFDataX (RTree d a) where+  deepErrorX x = pure (deepErrorX x)++  rnfX t = if isLeft (isX t) then () else go t+   where+    go :: RTree d a -> ()+    go (LR_ x)   = rnfX x+    go (BR_ l r) = rnfX l `seq` rnfX r++ -- | A /dependently/ typed fold over trees. -- -- As an example of when you might want to use 'dtfold' we will build a@@ -245,15 +268,15 @@ -- 'Index' ((2^d)+1) -> 'Index' ((2^d)+1) -> 'Index' ((2^(d+1))+1) -- @ ----- We have such an adder in the form of the 'Clash.Class.Num.plus' function, as+-- We have such an adder in the form of the 'Clash.Class.Num.add' function, as -- defined in the instance 'Clash.Class.Num.ExtendingNum' instance of 'Index'. -- However, we cannot simply use 'fold' to create a tree-structure of--- 'Clash.Class.Num.plus'es:+-- 'Clash.Class.Num.add'es: -- -- >>> :{ -- let populationCount' :: (KnownNat (2^d), KnownNat d, KnownNat (2^d+1)) --                      => BitVector (2^d) -> Index (2^d+1)---     populationCount' = tfold fromIntegral plus . v2t . bv2v+--     populationCount' = tfold fromIntegral add . v2t . bv2v -- :} -- <BLANKLINE> -- <interactive>:...@@ -264,9 +287,9 @@ --         Actual type: Index ((2 ^ d) + 1) --                      -> Index ((2 ^ d) + 1) --                      -> AResult (Index ((2 ^ d) + 1)) (Index ((2 ^ d) + 1))---     • In the second argument of ‘tfold’, namely ‘plus’---       In the first argument of ‘(.)’, namely ‘tfold fromIntegral plus’---       In the expression: tfold fromIntegral plus . v2t . bv2v+--     • In the second argument of ‘tfold’, namely ‘add’+--       In the first argument of ‘(.)’, namely ‘tfold fromIntegral add’+--       In the expression: tfold fromIntegral add . v2t . bv2v --     • Relevant bindings include --         populationCount' :: BitVector (2 ^ d) -> Index ((2 ^ d) + 1) --           (bound at ...)@@ -274,7 +297,7 @@ -- because 'tfold' expects a function of type \"@b -> b -> b@\", i.e. a function -- where the arguments and result all have exactly the same type. ----- In order to accommodate the type of our 'Clash.Class.Num.plus', where the+-- In order to accommodate the type of our 'Clash.Class.Num.add', where the -- result is larger than the arguments, we must use a dependently typed fold in -- the form of 'dtfold': --@@ -290,7 +313,7 @@ --                  => BitVector (2^k) -> Index ((2^k)+1) -- populationCount' bv = 'tdfold' (Proxy @IIndex) --                              fromIntegral---                              (\\_ x y -> 'Clash.Class.Num.plus' x y)+--                              (\\_ x y -> 'Clash.Class.Num.add' x y) --                              ('v2t' ('Clash.Sized.Vector.bv2v' bv)) -- @ --@@ -301,7 +324,7 @@ -- >>> populationCount' (7 :: BitVector 16) -- 3 tdfold :: forall p k a . KnownNat k-       => Proxy (p :: TyFun Nat * -> *) -- ^ The /motive/+       => Proxy (p :: TyFun Nat Type -> Type) -- ^ The /motive/        -> (a -> (p @@ 0)) -- ^ Function to apply to the elements on the leafs        -> (forall l . SNat l -> (p @@ l) -> (p @@ l) -> (p @@ (l+1)))        -- ^ Function to fold the branches with.@@ -317,7 +340,7 @@                       in  g sn' (go sn' l) (go sn' r) {-# NOINLINE tdfold #-} -data TfoldTree (a :: *) (f :: TyFun Nat *) :: *+data TfoldTree (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (TfoldTree a) d = a  -- | Reduce a tree to a single element@@ -353,7 +376,7 @@ trepeat :: KnownNat d => a -> RTree d a trepeat = treplicate SNat -data MapTree (a :: *) (f :: TyFun Nat *) :: *+data MapTree (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (MapTree a) d = RTree d a  -- | \"'tmap' @f t@\" is the tree obtained by apply /f/ to each element of /t/,@@ -374,7 +397,7 @@          (\s@SNat l r -> BR l (tmap (+(snatToNum (pow2SNat s))) r))          (treplicate SNat 0) -data V2TTree (a :: *) (f :: TyFun Nat *) :: *+data V2TTree (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (V2TTree a) d = RTree d a  -- | Convert a vector with /2^d/ elements to a tree of depth /d/.@@ -386,7 +409,7 @@ v2t :: forall d a . KnownNat d => Vec (2^d) a -> RTree d a v2t = dtfold (Proxy @(V2TTree a)) LR (const BR) -data T2VTree (a :: *) (f :: TyFun Nat *) :: *+data T2VTree (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (T2VTree a) d = Vec (2^d) a  -- | Convert a tree of depth /d/ to a vector of /2^d/ elements@@ -429,10 +452,10 @@ replaceTree :: (KnownNat d, Enum i) => i -> a -> RTree d a -> RTree d a replaceTree i a = v2t . replace i a . t2v -data ZipWithTree (b :: *) (c :: *) (f :: TyFun Nat *) :: *+data ZipWithTree (b :: Type) (c :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (ZipWithTree b c) d = RTree d b -> RTree d c --- | 'tzipWith' generalises 'tzip' by zipping with the function given as the+-- | 'tzipWith' generalizes 'tzip' by zipping with the function given as the -- first argument, instead of a tupling function. For example, "tzipWith (+)" -- applied to two trees produces the tree of corresponding sums. --@@ -456,7 +479,7 @@ tzip :: KnownNat d => RTree d a -> RTree d b -> RTree d (a,b) tzip = tzipWith (,) -data UnzipTree (a :: *) (b :: *) (f :: TyFun Nat *) :: *+data UnzipTree (a :: Type) (b :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (UnzipTree a b) d = (RTree d a, RTree d b)  -- | 'tunzip' transforms a tree of pairs into a tree of first components and a
src/Clash/Sized/Vector.hs view
@@ -6,7 +6,9 @@ -}  {-# LANGUAGE BangPatterns         #-}+{-# LANGUAGE CPP                  #-} {-# LANGUAGE DataKinds            #-}+{-# LANGUAGE FlexibleInstances    #-} {-# LANGUAGE GADTs                #-} {-# LANGUAGE KindSignatures       #-} {-# LANGUAGE MagicHash            #-}@@ -20,6 +22,9 @@ {-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns         #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  {-# LANGUAGE Trustworthy #-} @@ -32,7 +37,7 @@  module Clash.Sized.Vector   ( -- * 'Vec'tor data type-    Vec(Nil,(:>),(:<))+    Vec(Nil,(:>),(:<),Cons)     -- * Accessors     -- ** Length information   , length, lengthS@@ -55,7 +60,7 @@     -- *** Initialisation from a list   , listToVecTH     -- ** Concatenation-  , (++), (+>>), (<<+), concat+  , (++), (+>>), (<<+), concat, concatMap   , shiftInAt0, shiftInAtN , shiftOutFrom0, shiftOutFromN   , merge     -- * Modifying vectors@@ -69,11 +74,11 @@     -- ** Mapping   , map, imap, smap     -- ** Zipping-  , zipWith, zipWith3-  , zip, zip3+  , zipWith, zipWith3, zipWith4, zipWith5, zipWith6, zipWith7+  , zip, zip3, zip4, zip5, zip6, zip7   , izipWith     -- ** Unzipping-  , unzip, unzip3+  , unzip, unzip3, unzip4, unzip5, unzip6, unzip7     -- * Folding   , foldr, foldl, foldr1, foldl1, fold   , ifoldr, ifoldl@@ -90,7 +95,7 @@   , bv2v   , v2bv     -- * Misc-  , lazyV, VCons, asNatProxy+  , lazyV, VCons, asNatProxy, seqV, forceV, seqVX, forceVX     -- * Primitives     -- ** 'Traversable' instance   , traverse#@@ -102,36 +107,42 @@  import Control.DeepSeq            (NFData (..)) import qualified Control.Lens     as Lens hiding (pattern (:>), pattern (:<))-import Data.Default               (Default (..))+import Data.Constraint            ((:-)(..), Dict (..))+import Data.Constraint.Nat        (leZero)+import Data.Data+  (Data (..), Constr, DataType, Fixity (..), Typeable, mkConstr, mkDataType)+import Data.Default.Class         (Default (..)) import qualified Data.Foldable    as F-import Data.Bifunctor.Flip        (Flip (..))+import Data.Kind                  (Type) import Data.Proxy                 (Proxy (..)) import Data.Singletons.Prelude    (TyFun,Apply,type (@@)) import GHC.TypeLits               (CmpNat, KnownNat, Nat, type (+), type (-), type (*),                                    type (^), type (<=), natVal) import GHC.Base                   (Int(I#),Int#,isTrue#)+import GHC.Generics               hiding (Fixity (..)) import GHC.Prim                   ((==#),(<#),(-#)) import Language.Haskell.TH        (ExpQ) import Language.Haskell.TH.Syntax (Lift(..))-import Prelude                    hiding ((++), (!!), concat, drop, foldl,-                                          foldl1, foldr, foldr1, head, init,-                                          iterate, last, length, map, repeat,-                                          replicate, reverse, scanl, scanr,-                                          splitAt, tail, take, unzip, unzip3,-                                          zip, zip3, zipWith, zipWith3)+import Prelude                    hiding ((++), (!!), concat, concatMap, drop,+                                          foldl, foldl1, foldr, foldr1, head,+                                          init, iterate, last, length, map,+                                          repeat, replicate, reverse, scanl,+                                          scanr, splitAt, tail, take, unzip,+                                          unzip3, zip, zip3, zipWith, zipWith3) import qualified Prelude          as P import Test.QuickCheck            (Arbitrary (..), CoArbitrary (..)) import Unsafe.Coerce              (unsafeCoerce)  import Clash.Promoted.Nat-  (SNat (..), UNat (..), leToPlus, pow2SNat, snatProxy, snatToInteger, subSNat,-   withSNat, toUNat)+  (SNat (..), SNatLE (..), UNat (..), compareSNat, leToPlus, pow2SNat,+   snatProxy, snatToInteger, subSNat, withSNat, toUNat) import Clash.Promoted.Nat.Literals (d1) import Clash.Sized.Internal.BitVector (Bit, BitVector, (++#), split#) import Clash.Sized.Index          (Index) -import Clash.Class.BitPack (BitPack (..))-import Clash.XException    (ShowX (..), showsX, showsPrecXWith)+import Clash.Class.BitPack        (packXWith, BitPack (..))+import Clash.XException+  (ShowX (..), NFDataX (..), showsX, showsPrecXWith, seqX)  {- $setup >>> :set -XDataKinds@@ -180,7 +191,7 @@ let populationCount' :: (KnownNat k, KnownNat (2^k)) => BitVector (2^k) -> Index ((2^k)+1)     populationCount' bv = dtfold (Proxy @IIndex)                                  fromIntegral-                                 (\_ x y -> plus x y)+                                 (\_ x y -> add x y)                                  (bv2v bv) :} @@ -192,13 +203,60 @@ -- * Lists with their length encoded in their type -- * 'Vec'tor elements have an __ASCENDING__ subscript starting from 0 and --   ending at @'length' - 1@.-data Vec :: Nat -> * -> * where+data Vec :: Nat -> Type -> Type where   Nil  :: Vec 0 a   Cons :: a -> Vec n a -> Vec (n + 1) a +-- | In many cases, this Generic instance only allows generic+-- functions/instances over vectors of at least size 1, due to the+-- /n-1/ in the /Rep (Vec n a)/ definition.+--+-- We'll have to wait for things like+-- https://ryanglscott.github.io/2018/02/11/how-to-derive-generic-for-some-gadts/+-- before we can work around this limitation+instance KnownNat n => Generic (Vec n a) where+  type Rep (Vec n a) =+    D1 ('MetaData "Vec" "Clash.Data.Vector" "clash-prelude" 'False)+      (C1 ('MetaCons "Nil" 'PrefixI 'False) U1 :+:+       C1 ('MetaCons "Cons" 'PrefixI 'False)+        (S1 ('MetaSel 'Nothing+                'NoSourceUnpackedness+                'NoSourceStrictness+                'DecidedLazy)+            (Rec0 a) :*:+         S1 ('MetaSel 'Nothing+                'NoSourceUnpackedness+                'NoSourceStrictness+                'DecidedLazy)+            (Rec0 (Vec (n-1) a))))+  from Nil         = M1 (L1 (M1 U1))+  from (Cons x xs) = M1 (R1 (M1 (M1 (K1 x) :*: M1 (K1 xs))))+  to (M1 g) = case compareSNat (SNat @n) (SNat @0) of+    SNatLE -> case leZero @n of+      Sub Dict -> Nil+    SNatGT -> case g of+      R1 (M1 (M1 (K1 p) :*: M1 (K1 q))) -> Cons p q++instance (KnownNat n, Typeable a, Data a) => Data (Vec n a) where+  gunfold k z _ = case compareSNat (SNat @n) (SNat @0) of+    SNatLE -> case leZero @n of+      Sub Dict -> z Nil+    SNatGT -> k (k (z @(a -> Vec (n-1) a -> Vec n a) Cons))+  toConstr Nil        = cNil+  toConstr (Cons _ _) = cCons+  dataTypeOf _        = tVec++tVec :: DataType+tVec = mkDataType "Vec" [cNil, cCons]++cNil :: Constr+cNil = mkConstr tVec "Nil" [] Prefix++cCons :: Constr+cCons = mkConstr tVec "Cons" [] Prefix+ instance NFData a => NFData (Vec n a) where-  rnf Nil         = ()-  rnf (Cons x xs) = rnf x `seq` rnf xs+  rnf = foldl (\() -> rnf) ()  -- | Add an element to the head of a vector. --@@ -249,18 +307,8 @@           punc (x `Cons` xs)  = \s -> showsX x (',':punc xs s)  instance (KnownNat n, Eq a) => Eq (Vec n a) where-  (==) v1 v2-    | length v1 == 0 = True-    | otherwise      = fold @Bool @n (&&) (unsafeCoerce (zipWith (==) v1 v2))-  -- FIXME: the `unsafeCoerce` is a hack because the Clash compiler cannot deal-  -- with the existential length of the 'xs' in "Cons x xs".-  ---  -- Ideally we would write:-  ---  -- (==) Nil           _  = True-  -- (==) v1@(Cons _ _) v2 = fold (&&) (zipWith (==) v1 v2)-  ---  -- But the Clash compiler currently fails on that definition.+  (==) Nil _            = True+  (==) v1@(Cons _ _) v2 = fold (&&) (zipWith (==) v1 v2)  instance (KnownNat n, Ord a) => Ord (Vec n a) where   compare x y = foldr f EQ $ zipWith compare x y@@ -272,19 +320,19 @@   fs <*> xs = zipWith ($) fs xs  instance (KnownNat n, 1 <= n) => F.Foldable (Vec n) where-  fold a      = leToPlus @1 (Flip a) (fold mappend . runFlip)-  foldMap f a = leToPlus @1 (Flip (map f a)) (fold mappend . runFlip)-  foldr       = foldr-  foldl       = foldl-  foldr1 f a  = leToPlus @1 (Flip a) (foldr1 f . runFlip)-  foldl1 f a  = leToPlus @1 (Flip a) (foldl1 f . runFlip)-  toList      = toList-  null _      = False-  length      = length-  maximum a   = leToPlus @1 (Flip a) (fold (\x y -> if x >= y then x else y) . runFlip)-  minimum a   = leToPlus @1 (Flip a) (fold (\x y -> if x <= y then x else y) . runFlip)-  sum a       = leToPlus @1 (Flip a) (fold (+) . runFlip)-  product a   = leToPlus @1 (Flip a) (fold (*) . runFlip)+  fold      = leToPlus @1 @n $ fold mappend+  foldMap f = leToPlus @1 @n $ fold mappend . map f+  foldr     = foldr+  foldl     = foldl+  foldr1 f  = leToPlus @1 @n $ foldr1 f+  foldl1 f  = leToPlus @1 @n $ foldl1 f+  toList    = toList+  null _    = False+  length    = length+  maximum   = leToPlus @1 @n $ fold (\x y -> if x >= y then x else y)+  minimum   = leToPlus @1 @n $ fold (\x y -> if x <= y then x else y)+  sum       = leToPlus @1 @n $ fold (+)+  product   = leToPlus @1 @n $ fold (*)  instance Functor (Vec n) where   fmap = map@@ -300,6 +348,16 @@ instance (Default a, KnownNat n) => Default (Vec n a) where   def = repeat def +instance (NFDataX a, KnownNat n) => NFDataX (Vec n a) where+  deepErrorX x = repeat (deepErrorX x)++  rnfX v =+    -- foldl will fail if the spine of the vector is undefined, so we need to+    -- seqX the result of it. We need to use foldl so Clash won't treat it as+    -- a recursive function.+    seqX (foldl (\() -> rnfX) () v) ()++ {-# INLINE singleton #-} -- | Create a vector of one element --@@ -546,6 +604,14 @@ concat (x `Cons` xs) = x ++ concat xs {-# NOINLINE concat #-} +-- | Map a function over all the elements of a vector and concatentate the resulting vectors.+--+-- >>> concatMap (replicate d3) (1:>2:>3:>Nil)+-- <1,1,1,2,2,2,3,3,3>+concatMap :: (a -> Vec m b) -> Vec n a -> Vec (n * m) b+concatMap f xs = concat (map f xs)+{-# INLINE concatMap #-}+ -- | Split a vector of \(n * m)\ elements into a vector of \"vectors of length -- /m/\", where the length /m/ is given. --@@ -604,7 +670,7 @@ -- >>> :t imap (+) (2 :> 2 :> 2 :> 2 :> Nil) -- imap (+) (2 :> 2 :> 2 :> 2 :> Nil) :: Vec 4 (Index 4) -- >>> imap (+) (2 :> 2 :> 2 :> 2 :> Nil)--- <2,3,*** Exception: Clash.Sized.Index: result 4 is out of bounds: [0..3]+-- <2,3,*** Exception: X: Clash.Sized.Index: result 4 is out of bounds: [0..3] -- ... -- >>> imap (\i a -> fromIntegral i + a) (2 :> 2 :> 2 :> 2 :> Nil) :: Vec 4 (Unsigned 8) -- <2,3,4,5>@@ -623,7 +689,7 @@ -- | Zip two vectors with a functions that also takes the elements' indices. -- -- >>> izipWith (\i a b -> i + a + b) (2 :> 2 :> Nil)  (3 :> 3:> Nil)--- <*** Exception: Clash.Sized.Index: result 3 is out of bounds: [0..1]+-- <*** Exception: X: Clash.Sized.Index: result 3 is out of bounds: [0..1] -- ... -- >>> izipWith (\i a b -> fromIntegral i + a + b) (2 :> 2 :> Nil) (3 :> 3 :> Nil) :: Vec 2 (Unsigned 8) -- <5,6>@@ -714,7 +780,7 @@ elemIndex x = findIndex (x ==) {-# INLINE elemIndex #-} --- | 'zipWith' generalises 'zip' by zipping with the function given+-- | 'zipWith' generalizes 'zip' by zipping with the function given -- as the first argument, instead of a tupling function. -- For example, \"'zipWith' @(+)@\" applied to two vectors produces the -- vector of corresponding sums.@@ -733,7 +799,7 @@ zipWith f (x `Cons` xs) ys = f x (head ys) `Cons` zipWith f xs (tail ys) {-# NOINLINE zipWith #-} --- | 'zipWith3' generalises 'zip3' by zipping with the function given+-- | 'zipWith3' generalizes 'zip3' by zipping with the function given -- as the first argument, instead of a tupling function. -- -- > zipWith3 f (x1 :> x2 :> ... xn :> Nil) (y1 :> y2 :> ... :> yn :> Nil) (z1 :> z2 :> ... :> zn :> Nil) == (f x1 y1 z1 :> f x2 y2 z2 :> ... :> f xn yn zn :> Nil)@@ -749,6 +815,76 @@ zipWith3 f us vs ws = zipWith (\a (b,c) -> f a b c) us (zip vs ws) {-# INLINE zipWith3 #-} +-- 'zipWith4' is analogous to 'zipWith3', but with four vectors.+--+-- __NB:__ 'zipWith4' is /strict/ in its second argument, and /lazy/ its following+-- arguments. This matters when 'zipWith4' is used in a recursive setting. See+-- 'lazyV' for more information.+zipWith4+  :: (a -> b -> c -> d -> e)+  -> Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+zipWith4 f us vs ws xs =+  zipWith (\a (b,c,d) -> f a b c d) us (zip3 vs ws xs)+{-# INLINE zipWith4 #-}++-- 'zipWith5' is analogous to 'zipWith3', but with five vectors.+--+-- __NB:__ 'zipWith5' is /strict/ in its second argument, and /lazy/ its following+-- arguments. This matters when 'zipWith5' is used in a recursive setting. See+-- 'lazyV' for more information.+zipWith5+  :: (a -> b -> c -> d -> e -> f)+  -> Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+  -> Vec n f+zipWith5 f us vs ws xs ys =+  zipWith (\a (b,c,d,e) -> f a b c d e) us (zip4 vs ws xs ys)+{-# INLINE zipWith5 #-}++-- 'zipWith6' is analogous to 'zipWith3', but with six vectors.+--+-- __NB:__ 'zipWith6' is /strict/ in its second argument, and /lazy/ its following+-- arguments. This matters when 'zipWith6' is used in a recursive setting. See+-- 'lazyV' for more information.+zipWith6+  :: (a -> b -> c -> d -> e -> f -> g)+  -> Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+  -> Vec n f+  -> Vec n g+zipWith6 f us vs ws xs ys zs =+  zipWith (\u (v,w,x,y,z) -> f u v w x y z) us (zip5 vs ws xs ys zs)+{-# INLINE zipWith6 #-}++-- 'zipWith7' is analogous to 'zipWith3', but with seven vectors.+--+-- __NB:__ 'zipWith7' is /strict/ in its second argument, and /lazy/ its following+-- arguments. This matters when 'zipWith7' is used in a recursive setting. See+-- 'lazyV' for more information.+zipWith7+  :: (a -> b -> c -> d -> e -> f -> g -> h)+  -> Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+  -> Vec n f+  -> Vec n g+  -> Vec n h+zipWith7 f ts us vs ws xs ys zs =+  zipWith (\t (u,v,w,x,y,z) -> f t u v w x y z) ts (zip6 us vs ws xs ys zs)+{-# INLINE zipWith7 #-}+ -- | 'foldr', applied to a binary operator, a starting value (typically -- the right-identity of the operator), and a vector, reduces the vector -- using the binary operator, from right to left:@@ -985,7 +1121,7 @@ zip = zipWith (,) {-# INLINE zip #-} --- | 'zip' takes three vectors and returns a vector of corresponding triplets.+-- | 'zip3' takes three vectors and returns a vector of corresponding triplets. -- -- >>> zip3 (1:>2:>3:>4:>Nil) (4:>3:>2:>1:>Nil) (5:>6:>7:>8:>Nil) -- <(1,4,5),(2,3,6),(3,2,7),(4,1,8)>@@ -993,6 +1129,45 @@ zip3 = zipWith3 (,,) {-# INLINE zip3 #-} +-- | 'zip4' takes four vectors and returns a list of quadruples, analogous+-- to 'zip'.+zip4 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n (a,b,c,d)+zip4 = zipWith4 (,,,)+{-# INLINE zip4 #-}++-- | 'zip5' takes five vectors and returns a list of five-tuples, analogous+-- to 'zip'.+zip5 :: Vec n a -> Vec n b -> Vec n c -> Vec n d -> Vec n e -> Vec n (a,b,c,d,e)+zip5 = zipWith5 (,,,,)+{-# INLINE zip5 #-}++-- | 'zip6' takes six vectors and returns a list of six-tuples, analogous+-- to 'zip'.+zip6+  :: Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+  -> Vec n f+  -> Vec n (a,b,c,d,e,f)+zip6 = zipWith6 (,,,,,)+{-# INLINE zip6 #-}++-- | 'zip7' takes seven vectors and returns a list of seven-tuples, analogous+-- to 'zip'.+zip7+  :: Vec n a+  -> Vec n b+  -> Vec n c+  -> Vec n d+  -> Vec n e+  -> Vec n f+  -> Vec n g+  -> Vec n (a,b,c,d,e,f,g)+zip7 = zipWith7 (,,,,,,)+{-# INLINE zip7 #-}+ -- | 'unzip' transforms a vector of pairs into a vector of first components -- and a vector of second components. --@@ -1014,6 +1189,57 @@             ) {-# INLINE unzip3 #-} +-- | 'unzip4' takes a vector of quadruples and returns four vectors, analogous+-- to 'unzip'.+unzip4 :: Vec n (a,b,c,d) -> (Vec n a, Vec n b, Vec n c, Vec n d)+unzip4 xs = ( map (\(w,_,_,_) -> w) xs+            , map (\(_,x,_,_) -> x) xs+            , map (\(_,_,y,_) -> y) xs+            , map (\(_,_,_,z) -> z) xs+            )+{-# INLINE unzip4 #-}++-- | 'unzip5' takes a vector of five-tuples and returns five vectors, analogous+-- to 'unzip'.+unzip5 :: Vec n (a,b,c,d,e) -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e)+unzip5 xs = ( map (\(v,_,_,_,_) -> v) xs+            , map (\(_,w,_,_,_) -> w) xs+            , map (\(_,_,x,_,_) -> x) xs+            , map (\(_,_,_,y,_) -> y) xs+            , map (\(_,_,_,_,z) -> z) xs+            )+{-# INLINE unzip5 #-}++-- | 'unzip6' takes a vector of six-tuples and returns six vectors, analogous+-- to 'unzip'.+unzip6+  :: Vec n (a,b,c,d,e,f)+  -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e, Vec n f)+unzip6 xs = ( map (\(u,_,_,_,_,_) -> u) xs+            , map (\(_,v,_,_,_,_) -> v) xs+            , map (\(_,_,w,_,_,_) -> w) xs+            , map (\(_,_,_,x,_,_) -> x) xs+            , map (\(_,_,_,_,y,_) -> y) xs+            , map (\(_,_,_,_,_,z) -> z) xs+            )+{-# INLINE unzip6 #-}++-- | 'unzip7' takes a vector of seven-tuples and returns seven vectors, analogous+-- to 'unzip'.+unzip7+  :: Vec n (a,b,c,d,e,f,g)+  -> (Vec n a, Vec n b, Vec n c, Vec n d, Vec n e, Vec n f, Vec n g)+unzip7 xs = ( map (\(t,_,_,_,_,_,_) -> t) xs+            , map (\(_,u,_,_,_,_,_) -> u) xs+            , map (\(_,_,v,_,_,_,_) -> v) xs+            , map (\(_,_,_,w,_,_,_) -> w) xs+            , map (\(_,_,_,_,x,_,_) -> x) xs+            , map (\(_,_,_,_,_,y,_) -> y) xs+            , map (\(_,_,_,_,_,_,z) -> z) xs+            )+{-# INLINE unzip7 #-}++ index_int :: KnownNat n => Vec n a -> Int -> a index_int xs i@(I# n0)   | isTrue# (n0 <# 0#) = error "Clash.Sized.Vector.(!!): negative index"@@ -1129,8 +1355,8 @@ -- <1,2> -- >>> drop d4               (1:>2:>Nil) -- <BLANKLINE>--- <interactive>:...---     • Couldn't match expected type ‘2’ with actual type ‘4 + n0’+-- <interactive>:...: error:+--     • Couldn't match...type ‘4 + n0... --       The type variable ‘n0’ is ambiguous --     • In the first argument of ‘print’, namely ‘it’ --       In a stmt of an interactive GHCi command: print it@@ -1225,7 +1451,7 @@ -- >>> iterate d4 (+1) 1 -- <1,2,3,4> ----- \"'interate' @n f z@\" corresponds to the following circuit layout:+-- \"'iterate' @n f z@\" corresponds to the following circuit layout: -- -- <<doc/iterate.svg>> iterate :: SNat n -> (a -> a) -> a -> Vec n a@@ -1240,7 +1466,7 @@ -- >>> iterateI (+1) 1 :: Vec 3 Int -- <1,2,3> ----- \"'interateI' @f z@\" corresponds to the following circuit layout:+-- \"'iterateI' @f z@\" corresponds to the following circuit layout: -- -- <<doc/iterate.svg>> iterateI :: KnownNat n => (a -> a) -> a -> Vec n a@@ -1377,7 +1603,7 @@ {-# INLINE windows2d #-}  -- | Forward permutation specified by an index mapping, /ix/. The result vector--- is initialised by the given defaults, /def/, and an further values that are+-- is initialized by the given defaults, /def/, and an further values that are -- permuted into the result are added to the current value using the given -- combination function, /f/. --@@ -1712,7 +1938,7 @@ -- or delay, of O(@'length' xs@). Look at 'dtfold' for a /dependently/ typed -- fold that produces a structure with a depth of O(log_2(@'length' xs@)). dfold :: forall p k a . KnownNat k-      => Proxy (p :: TyFun Nat * -> *) -- ^ The /motive/+      => Proxy (p :: TyFun Nat Type -> Type) -- ^ The /motive/       -> (forall l . SNat l -> a -> (p @@ l) -> (p @@ (l + 1)))       -- ^ Function to fold.       --@@ -1764,15 +1990,15 @@ -- 'Index' ((2^d)+1) -> 'Index' ((2^d)+1) -> 'Index' ((2^(d+1))+1) -- @ ----- We have such an adder in the form of the 'Clash.Class.Num.plus' function, as+-- We have such an adder in the form of the 'Clash.Class.Num.add' function, as -- defined in the instance 'Clash.Class.Num.ExtendingNum' instance of 'Index'. -- However, we cannot simply use 'fold' to create a tree-structure of--- 'Clash.Class.Num.plus'es:+-- 'Clash.Class.Num.add'es: -- -- >>> :{ -- let populationCount' :: (KnownNat (n+1), KnownNat (n+2)) --                      => BitVector (n+1) -> Index (n+2)---     populationCount' = fold plus . map fromIntegral . bv2v+--     populationCount' = fold add . map fromIntegral . bv2v -- :} -- <BLANKLINE> -- <interactive>:...@@ -1780,9 +2006,9 @@ --       Expected type: Index (n + 2) -> Index (n + 2) -> Index (n + 2) --         Actual type: Index (n + 2) --                      -> Index (n + 2) -> AResult (Index (n + 2)) (Index (n + 2))---     • In the first argument of ‘fold’, namely ‘plus’---       In the first argument of ‘(.)’, namely ‘fold plus’---       In the expression: fold plus . map fromIntegral . bv2v+--     • In the first argument of ‘fold’, namely ‘add’+--       In the first argument of ‘(.)’, namely ‘fold add’+--       In the expression: fold add . map fromIntegral . bv2v --     • Relevant bindings include --         populationCount' :: BitVector (n + 1) -> Index (n + 2) --           (bound at ...)@@ -1790,7 +2016,7 @@ -- because 'fold' expects a function of type \"@a -> a -> a@\", i.e. a function -- where the arguments and result all have exactly the same type. ----- In order to accommodate the type of our 'Clash.Class.Num.plus', where the+-- In order to accommodate the type of our 'Clash.Class.Num.add', where the -- result is larger than the arguments, we must use a dependently typed fold in -- the form of 'dtfold': --@@ -1806,7 +2032,7 @@ --                  => BitVector (2^k) -> Index ((2^k)+1) -- populationCount' bv = 'dtfold' (Proxy @IIndex) --                              fromIntegral---                              (\\_ x y -> 'Clash.Class.Num.plus' x y)+--                              (\\_ x y -> 'Clash.Class.Num.add' x y) --                              ('bv2v' bv) -- @ --@@ -1830,7 +2056,7 @@ -- __NB__: The depth, or delay, of the structure produced by -- \"@'dtfold' m f g xs@\" is O(log_2(@'length' xs@)). dtfold :: forall p k a . KnownNat k-       => Proxy (p :: TyFun Nat * -> *) -- ^ The /motive/+       => Proxy (p :: TyFun Nat Type -> Type) -- ^ The /motive/        -> (a -> (p @@ 0)) -- ^ Function to apply to every element        -> (forall l . SNat l -> (p @@ l) -> (p @@ l) -> (p @@ (l + 1)))        -- ^ Function to combine results.@@ -1861,7 +2087,7 @@ -- map' :: forall n a b . KnownNat n => (a -> b) -> Vec n a -> Vec n b -- map' f = 'dfold' (Proxy @('VCons' b)) (\_ x xs -> f x :> xs) -- @-data VCons (a :: *) (f :: TyFun Nat *) :: *+data VCons (a :: Type) (f :: TyFun Nat Type) :: Type type instance Apply (VCons a) l = Vec l a  -- | Specialised version of 'dfold' that builds a triangular computational@@ -1908,7 +2134,7 @@  instance (KnownNat n, KnownNat (BitSize a), BitPack a) => BitPack (Vec n a) where   type BitSize (Vec n a) = n * (BitSize a)-  pack   = concatBitVector# . map pack+  pack   = packXWith (concatBitVector# . map pack)   unpack = map unpack . unconcatBitVector#  concatBitVector#@@ -1951,6 +2177,49 @@ -- 0001_0010 v2bv :: KnownNat n => Vec n Bit -> BitVector n v2bv = pack++-- | Evaluate all elements of a vector to WHNF, returning the second argument+seqV+  :: KnownNat n+  => Vec n a+  -> b+  -> b+seqV v b =+  let s () e = seq e () in+  foldl s () v `seq` b+{-# NOINLINE seqV #-}+infixr 0 `seqV`++-- | Evaluate all elements of a vector to WHNF+forceV+  :: KnownNat n+  => Vec n a+  -> Vec n a+forceV v =+  v `seqV` v+{-# INLINE forceV #-}++-- | Evaluate all elements of a vector to WHNF, returning the second argument.+-- Does not propagate 'XException's.+seqVX+  :: KnownNat n+  => Vec n a+  -> b+  -> b+seqVX v b =+  let s () e = seqX e () in+  foldl s () v `seqX` b+{-# NOINLINE seqVX #-}+infixr 0 `seqVX`++-- | Evaluate all elements of a vector to WHNF. Does not propagate 'XException's.+forceVX+  :: KnownNat n+  => Vec n a+  -> Vec n a+forceVX v =+  v `seqVX` v+{-# INLINE forceVX #-}  instance Lift a => Lift (Vec n a) where   lift Nil           = [| Nil |]
src/Clash/Tutorial.hs view
@@ -1,2388 +1,2546 @@ {-| Copyright : © 2014-2016, Christiaan Baaij,-              2017     , Myrtle Software Ltd, QBayLogic, Google Inc.-Licence   : Creative Commons 4.0 (CC BY 4.0) (http://creativecommons.org/licenses/by/4.0/)--}--{-# LANGUAGE NoImplicitPrelude, MagicHash #-}-{-# OPTIONS_GHC -fno-warn-unused-imports #-}--module Clash.Tutorial (-  -- * Introduction-  -- $introduction--  -- * Installation-  -- $installation--  -- * Working with this tutorial-  -- $working--  -- * Your first circuit-  -- $mac_example--  -- *** Sequential circuit-  -- $mac2--  -- *** Generating VHDL-  -- $mac3--  -- *** Circuit testbench-  -- $mac4--  -- *** Generating Verilog and SystemVerilog-  -- $mac5--  -- *** Alternative specifications-  -- $mac6--  -- * Higher-order functions-  -- $higher_order--  -- * Composition of sequential circuits-  -- $composition_sequential--  -- * Synthesize annotations: controlling the VHDL\/(System)Verilog generation.-  -- $annotations--  -- * Multiple clock domains-  -- $multiclock--  -- * Advanced: Primitives-  -- $primitives--  -- *** Verilog primitives-  -- $vprimitives--  -- *** SystemVerilog primitives-  -- $svprimitives--  -- * Conclusion-  -- $conclusion--  -- * Troubleshooting-  -- $errorsandsolutions--  -- * Limitations of CλaSH-  -- $limitations--  -- * CλaSH vs Lava-  -- $vslava--  -- * Migration guide from Clash 0.7-  -- $migration-  )-where--import Clash.Prelude-import Clash.Explicit.Prelude (freqCalc)-import Clash.Explicit.Testbench-import Control.Monad.ST-import Data.Array-import Data.Char-import Data.Int-import GHC.Prim-import GHC.TypeLits-import GHC.Word-import Data.Default--{- $setup->>> :set -XTemplateHaskell -XDataKinds -XConstraintKinds -XTypeApplications->>> :{-let ma :: Num a => a -> (a, a) -> a-    ma acc (x,y) = acc + x * y-:}-->>> :{-let macT :: Num a => a -> (a,a) -> (a,a)-    macT acc (x,y) = (acc',o)-       where-         acc' = ma acc (x,y)-         o    = acc-:}-->>> :set -XFlexibleContexts->>> :set -fplugin GHC.TypeLits.Normalise->>> let compareSwapL a b = if a < b then (a,b) else (b,a)->>> :{-let sortV xs = map fst sorted :< (snd (last sorted))-      where-        lefts  = head xs :> map snd (init sorted)-        rights = tail xs-        sorted = zipWith compareSwapL lefts rights-:}-->>> :{-let sortVL xs = map fst sorted :< (snd (last sorted))-      where-        lefts  = head xs :> map snd (init sorted)-        rights = tail xs-        sorted = zipWith compareSwapL (lazyV lefts) rights-:}-->>> let mac = mealy macT 0->>> :{-topEntity :: Clock System Source -> Reset System Asynchronous -> Signal System (Signed 9, Signed 9) -> Signal System (Signed 9)-topEntity = exposeClockReset mac-:}-->>> :{-let testBench :: Signal System Bool-    testBench = done-      where-        testInput      = stimuliGenerator clk rst $(listToVecTH [(1,1) :: (Signed 9,Signed 9),(2,2),(3,3),(4,4)])-        expectedOutput = outputVerifier clk rst $(listToVecTH [0 :: Signed 9,1,5,14])-        done           = expectedOutput (topEntity clk rst testInput)-        clk            = tbSystemClockGen (not <$> done)-        rst            = systemResetGen-:}-->>> :{-let fibR :: Unsigned 64 -> Unsigned 64-    fibR 0 = 0-    fibR 1 = 1-    fibR n = fibR (n-1) + fibR (n-2)-:}-->>> :{-let fibS :: SystemClockReset => Signal System (Unsigned 64)-    fibS = r-      where r = register 0 r + register 0 (register 1 r)-:}---}--{- $introduction-CλaSH (pronounced ‘clash’) is a functional hardware description language that-borrows both its syntax and semantics from the functional programming language-Haskell. It provides a familiar structural design approach to both combination-and synchronous sequential circuits. The CλaSH compiler transforms these-high-level descriptions to low-level synthesizable VHDL, Verilog, or-SystemVerilog.--Features of CλaSH:--  * Strongly typed, but with a very high degree of type inference, enabling-    both safe and fast prototyping using concise descriptions.-  * Interactive REPL: load your designs in an interpreter and easily test all-    your component without needing to setup a test bench.-  * Compile your designs for fast simulation.-  * Higher-order functions, in combination with type inference, result in-    designs that are fully parametric by default.-  * Synchronous sequential circuit design based on streams of values, called-    @Signal@s, lead to natural descriptions of feedback loops.-  * Multiple clock domains, with type safe clock domain crossing.-  * Template language for introducing new VHDL/(System)Verilog primitives.--Although we say that CλaSH borrows the semantics of Haskell, that statement-should be taken with a grain of salt. What we mean to say is that the CλaSH-compiler views a circuit description as /structural/ description. This means,-in an academic handwavy way, that every function denotes a component and every-function application denotes an instantiation of said component. Now, this has-consequences on how we view /recursively/ defined functions: structurally, a-recursively defined function would denote an /infinitely/ deep / structured-component, something that cannot be turned into an actual circuit-(See also <#limitations Limitations of CλaSH>).--On the other hand, Haskell's by-default non-strict evaluation works very well-for the simulation of the feedback loops, which are ubiquitous in digital-circuits. That is, when we take our structural view to circuit descriptions,-value-recursion corresponds directly to a feedback loop:--@-counter = s-  where-    s = 'register' 0 (s + 1)-@--The above definition, which uses value-recursion, /can/ be synthesized to a-circuit by the CλaSH compiler.--Over time, you will get a better feeling for the consequences of taking a-/structural/ view on circuit descriptions. What is always important to-remember is that every applied functions results in an instantiated component,-and also that the compiler will /never/ infer / invent more logic than what is-specified in the circuit description.--With that out of the way, let us continue with installing CλaSH and building-our first circuit.--}--{- $installation-The CλaSH compiler and Prelude library for circuit design only work with the-<http://haskell.org/ghc GHC> Haskell compiler version 8.2.1 or higher.--  (1) Install __GHC 8.2.1 or higher__--      * Download and install <https://www.haskell.org/ghc/download_ghc_8_4_3 GHC for your platform>.-        Unix user can use @./configure prefix=\<LOCATION\>@ to set the installation-        location.--      * Make sure that the @bin@ directory of __GHC__ is in your @PATH@.--    In case you cannot find what you are looking for on <https://www.haskell.org/ghc/download_ghc_8_4_3>,-    you can, /alternatively/, use the following instructions:--      * Ubuntu:--          * Run: @sudo add-apt-repository -y ppa:hvr/ghc@-          * Run: @sudo apt-get update@-          * Run: @sudo apt-get install cabal-install-2.2 ghc-8.4.3 libtinfo-dev@-          * Update your @PATH@ with: @\/opt\/ghc\/bin@, @\/opt\/cabal\/bin@, and @\$HOME\/.cabal\/bin@-          * Run: @cabal update@-          * Skip step 2.--      * OS X:--          * Follow the instructions on: <https://www.haskell.org/platform/mac.html Haskell Platform Mac OS X>-            to install the /minimal/ Haskell platform-          * Run: @cabal update@-          * Skip step 2.--      * Windows:--          * Follow the instructions on: <https://www.haskell.org/platform/windows.html Haskell Platform Windows>-            to install the /minimal/ Haskell platform-          * Run: @cabal update@-          * Skip step 2.--  (2) Install __Cabal (version 2.2 or higher)__--      * Binary, when available:--          * Download the binary for <http://www.haskell.org/cabal/download.html cabal-install>-          * Put the binary in a location mentioned in your @PATH@-          * Add @cabal@'s @bin@ directory to your @PATH@:--              * Windows: @%appdata%\\cabal\\bin@-              * Unix: @\$HOME\/.cabal\/bin@--      * Source:--          * Download the sources for <http://hackage.haskell.org/package/cabal-install cabal-install>-          * Unpack (@tar xf@) the archive and @cd@ to the directory-          * Run: @sh bootstrap.sh@-          * Follow the instructions to add @cabal@ to your @PATH@--      * Run @cabal update@--  (2) Install __CλaSH__--      * Run:--          * Linux: @cabal install clash-ghc --enable-documentation --enable-executable-dynamic@-          * Other: @cabal install clash-ghc --enable-documentation@--      * /This is going to take awhile, so have a refreshment/--  (4) Verify that everything is working by:--      * Downloading the <https://raw.githubusercontent.com/clash-lang/clash-compiler/4bfeb5a63e8c0dddc34d2d973c2200d01f71acee/examples/FIR.hs Fir.hs> example-      * Run: @clashi FIR.hs@-      * Execute, in the interpreter, the @:vhdl@ command-      * Execute, in the interpreter, the @:verilog@ command-      * Execute, in the interpreter, the @:systemverilog@ command-      * Exit the interpreter using @:q@-      * Examine the VHDL code in the @vhdl@ directory-      * Examine the Verilog code in the @verilog@ directory-      * Examine the SystemVerilog code in the @systemverilog@ directory---}--{- $working-This tutorial can be followed best whilst having the CλaSH interpreter running-at the same time. If you followed the installation instructions, you already-know how to start the CλaSH compiler in interpretive mode:--@-clashi-@--For those familiar with Haskell/GHC, this is indeed just @GHCi@, with three-added commands (@:vhdl@, @:verilog@, and @:systemverilog@). You can load files-into the interpreter using the @:l \<FILENAME\>@ command. Now, depending on your-choice in editor, the following @edit-load-run@ cycle probably work best for you:--  * __Commandline (e.g. emacs, vim):__--      * You can run system commands using @:!@, for example @:! touch \<FILENAME\>@-      * Set the /editor/ mode to your favourite editor using: @:set editor \<EDITOR\>@-      * You can load files using @:l@ as noted above.-      * You can go into /editor/ mode using: @:e@-      * Leave the editor mode by quitting the editor (e.g. @:wq@ in @vim@)--  * __GUI (e.g. SublimeText, Notepad++):__--      * Just create new files in your editor.-      * Load the files using @:l@ as noted above.-      * Once a file has been edited and saved, type @:r@ to reload the files in-        the interpreter--You are of course free to deviate from these suggestions as you see fit :-) It-is just recommended that you have the CλaSH interpreter open during this-tutorial.--}--{- $mac_example-The very first circuit that we will build is the \"classic\" multiply-and-accumulate-(MAC) circuit. This circuit is as simple as it sounds, it multiplies its inputs-and accumulates them. Before we describe any logic, we must first create the-file we will be working on and input some preliminaries:--* Create the file:--    @-    MAC.hs-    @--* Write on the first line the module header:--    @-    module MAC where-    @--    Module names must always start with a __C__apital letter. Also make sure that-    the file name corresponds to the module name.--* Add the import statement for the CλaSH prelude library:--    @-    import Clash.Prelude-    @--    This imports all the necessary functions and datatypes for circuit description.--We can now finally start describing the logic of our circuit, starting with just-the multiplication and addition:--@-ma acc (x,y) = acc + x * y-@--If you followed the instructions of running the interpreter side-by-side, you-can already test this function:-->>> ma 4 (8,9)-76->>> ma 2 (3,4)-14--We can also examine the inferred type of @ma@ in the interpreter:-->>> :t ma-ma :: Num a => a -> (a, a) -> a--Talking about /types/ also brings us to one of the most important parts of this-tutorial: /types/ and /synchronous sequential logic/. Especially how we can-always determine, through the types of a specification, if it describes-combinational logic or (synchronous) sequential logic. We do this by examining-the type of one of the sequential primitives, the @'register'@ function:--@-register-  :: 'HiddenClockReset' domain gated synchronous-  => a -> 'Signal' domain a -> 'Signal' domain a-register i s = ...-@--Where we see that the second argument and the result are not just of the-/polymorphic/ @a@ type, but of the type: @'Signal' a@. All (synchronous)-sequential circuits work on values of type @'Signal' a@. Combinational-circuits always work on values of, well, not of type @'Signal' a@. A 'Signal'-is an (infinite) list of samples, where the samples correspond to the values-of the 'Signal' at discrete, consecutive, ticks of the /clock/. All (sequential)-components in the circuit are synchronized to this global /clock/. For the-rest of this tutorial, and probably at any moment where you will be working with-CλaSH, you should probably not actively think about 'Signal's as infinite lists-of samples, but just as values that are manipulated by sequential circuits. To-make this even easier, it actually not possible to manipulate the underlying-representation directly: you can only modify 'Signal' values through a set of-primitives such as the 'register' function above.--Now, let us get back to the functionality of the 'register' function: it is-a simple @latch@ that only changes state at the tick of the global /clock/, and-it has an initial value @a@ which is its output at time 0. We can further-examine the 'register' function by taking a look at the first 4 samples of the-'register' functions applied to a constant signal with the value 8:-->>> sampleN 4 (register 0 (pure 8))-[0,8,8,8]--Where we see that the initial value of the signal is the specified 0 value,-followed by 8's.--}--{- $mac2-The 'register' function is our primary sequential building block to capture-/state/. It is used internally by one of the "Clash.Prelude" function that we-will use to describe our MAC circuit. Note that the following paragraphs will-only show one of many ways to specify a sequential circuit, at the section we-will show a couple more.--A principled way to describe a sequential circuit is to use one of the classic-machine models, within the CλaSH prelude library offer standard function to-support the <http://en.wikipedia.org/wiki/Mealy_machine Mealy machine>.-To improve sharing, we will combine the transition function and output function-into one. This gives rise to the following Mealy specification of the MAC-circuit:--@-macT acc (x,y) = (acc',o)-  where-    acc' = ma acc (x,y)-    o    = acc-@--Note that the @where@ clause and explicit tuple are just for demonstrative-purposes, without loss of sharing we could've also written:--@-macT acc inp = (ma acc inp,acc)-@--Going back to the original specification we note the following:--  * 'acc' is the current /state/ of the circuit.-  * '(x,y)' is its input.-  * 'acc'' is the updated, or next, /state/.-  * 'o' is the output.--When we examine the type of 'macT' we see that is still completely combinational:-->>> :t macT-macT :: Num a => a -> (a, a) -> (a, a)--The "Clash.Prelude" library contains a function that creates a sequential-circuit from a combinational circuit that has the same Mealy machine type /-shape of @macT@:--@-mealy-  :: 'HiddenClockReset' domain gated synchronous-  => (s -> i -> (s,o))-  -> s-  -> ('Signal' i -> 'Signal' o)-mealy f initS = ...-@--The complete sequential MAC circuit can now be specified as:--@-mac = 'mealy' macT 0-@--Where the first argument of @'mealy'@ is our @macT@ function, and the second-argument is the initial state, in this case 0. We can see it is functioning-correctly in our interpreter:-->>> import qualified Data.List as L->>> L.take 4 $ simulate mac [(1,1),(2,2),(3,3),(4,4)]-[0,1,5,14]--Where we simulate our sequential circuit over a list of input samples and take-the first 4 output samples. We have now completed our first sequential circuit-and have made an initial confirmation that it is working as expected.--}--{- $mac3-We are now almost at the point that we can create actual hardware, in the form-of a <http://en.wikipedia.org/wiki/VHDL VHDL> netlist, from our sequential-circuit specification. The first thing we have to do is create a function-called 'topEntity' and ensure that it has a __monomorphic__ type. In our case-that means that we have to give it an explicit type annotation. It might not-always be needed, you can always check the type with the @:t@ command and see-if the function is monomorphic:--@-topEntity-  :: 'Clock' System 'Source'-  -> 'Reset' System 'Asynchronous'-  -> 'Signal' System ('Signed' 9, 'Signed' 9)-  -> 'Signal' System ('Signed' 9)-topEntity = exposeClockReset mac-@--Which makes our circuit work on 9-bit signed integers. Including the above-definition, our complete @MAC.hs@ should now have the following content:--@-module MAC where--import Clash.Prelude--ma acc (x,y) = acc + x * y--macT acc (x,y) = (acc',o)-  where-    acc' = ma acc (x,y)-    o    = acc--mac = 'mealy' macT 0--topEntity-  :: 'Clock' System 'Source'-  -> 'Reset' System 'Asynchronous'-  -> 'Signal' System ('Signed' 9, 'Signed' 9)-  -> 'Signal' System ('Signed' 9)-topEntity = 'exposeClockReset' mac-@--The 'topEntity' function is the starting point for the CλaSH compiler to-transform your circuit description into a VHDL netlist. It must meet the-following restrictions in order for the CλaSH compiler to work:--  * It must be completely monomorphic-  * It must be completely first-order-  * Although not strictly necessary, it is recommended to /expose/ 'Hidden'-    clock and reset arguments, as it makes user-controlled-    <Clash-Tutorial.html#annotations name assignment> in the generated HDL-    easier to do.--Our 'topEntity' meets those restrictions, and so we can convert it successfully-to VHDL by executing the @:vhdl@ command in the interpreter. This will create-a directory called 'vhdl', which contains a directory called @MAC@, which-ultimately contains all the generated VHDL files. You can now load these files-into your favourite VHDL synthesis tool, marking @mac_topentity.vhdl@ as the file-containing the top level entity.--}--{- $mac4-There are multiple reasons as to why might you want to create a so-called-/test bench/ for the generated HDL:--  * You want to compare post-synthesis / post-place&route behaviour to that of-    the behaviour of the original generated HDL.-  * Need representative stimuli for your dynamic power calculations-  * Verify that the HDL output of the CλaSH compiler has the same behaviour as-    the Haskell / CλaSH specification.--For these purposes, you can have CλaSH compiler generate a /test bench/. In-order for the CλaSH compiler to do this you need to do one of the following:--  * Create a function called /testBench/ in the root module.-  * Annotate your /topEntity/ function (or function with a-    <Clash-Tutorial.html#g:12 Synthesize> annotation)-    with a 'TestBench' annotation.--For example, you can test the earlier defined /topEntity/ by:--@-import Clash.Explicit.Testbench--topEntity-  :: 'Clock' System 'Source'-  -> 'Reset' System 'Asynchronous'-  -> 'Signal' System ('Signed' 9, 'Signed' 9)-  -> 'Signal' System ('Signed' 9)-topEntity = 'exposeClockReset' mac-{\-\# NOINLINE topEntity \#-\}--testBench :: 'Signal' System Bool-testBench = done-  where-    testInput    = 'stimuliGenerator' clk rst $('listToVecTH' [(1,1) :: ('Signed' 9,'Signed' 9),(2,2),(3,3),(4,4)])-    expectOutput = 'outputVerifier' clk rst $('listToVecTH' [0 :: 'Signed' 9,1,5,14])-    done         = expectOutput (topEntity clk rst testInput)-    clk          = 'tbSystemClockGen' (not '<$>' done)-    rst          = 'systemResetGen'-@--This will create a stimulus generator that creates the same inputs as we used-earlier for the simulation of the circuit, and creates an output verifier that-compares against the results we got from our earlier simulation. We can even-simulate the behaviour of the /testBench/:-->>> sampleN 7 testBench-[False,False,False,False-cycle(system10000): 4, outputVerifier-expected value: 14, not equal to actual value: 30-,True-cycle(system10000): 5, outputVerifier-expected value: 14, not equal to actual value: 46-,True-cycle(system10000): 6, outputVerifier-expected value: 14, not equal to actual value: 62-,True]--We can see that for the first 4 samples, everything is working as expected,-after which warnings are being reported. The reason is that 'stimuliGenerator'-will keep on producing the last sample, (4,4), while the 'outputVerifier' will-keep on expecting the last sample, 14. In the VHDL testbench these errors won't-show, as the global clock will be stopped after 4 ticks.--You should now again run @:vhdl@ in the interpreter; this time the compiler-will take a bit longer to generate all the circuits. Inside the @.\/vhdl\/MAC@-directory you will now also find a /mac_testbench/ subdirectory containing all-the @vhdl@ files for the /test bench/---After compilation is finished you  load all the files in your favourite VHDL-simulation tool. Once all files are loaded into the VHDL simulator, run the-simulation on the @mac_testbench_testbench@ entity.-On questasim / modelsim: doing a @run -all@ will finish once the output verifier-will assert its output to @true@. The generated testbench, modulo the clock-signal generator(s), is completely synthesizable. This means that if you want to-test your circuit on an FPGA, you will only have to replace the clock signal-generator(s) by actual clock sources, such as an onboard PLL.--}--{- $mac5-Aside from being to generate VHDL, the CλaSH compiler can also generate Verilog-and SystemVerilog. You can repeat the previous two parts of the tutorial, but-instead of executing the @:vhdl@ command, you execute the @:verilog@ or-@:sytemverilog@ command in the interpreter. This will create a directory called-@verilog@, respectively @systemverilog@, which contains a directory called @MAC@,-which ultimately contains all the generated Verilog and SystemVerilog files.-Verilog files end in the file extension @v@, while SystemVerilog files end in-the file extension @sv@.--This concludes the main part of this section on \"Your first circuit\", read on-for alternative specifications for the same 'mac' circuit, or just skip to the-next section where we will describe another DSP classic: an FIR filter-structure.--}--{- $mac6-* __'Num' instance for 'Signal'__:--    @'Signal' a@ is also also considered a 'Num'eric type as long as the value-    type /a/ is also 'Num'eric.  This means that we can also use the standard-    numeric operators, such as ('*') and ('+'), directly on signals. An-    alternative specification of the 'mac' circuit will also use the 'register'-    function directly:--    @-    macN (x,y) = acc-      where-        acc = 'register' 0 (acc + x * y)-    @--* __'Applicative' instance for 'Signal'__:--    We can also mix the combinational 'ma' function, with the sequential-    'register' function, by lifting the 'ma' function to the sequential 'Signal'-    domain using the operators ('<$>' and '<*>') of the 'Applicative' type-    class:--    @-    macA (x,y) = acc-      where-        acc  = 'register' 0 acc'-        acc' = ma '<$>' acc '<*>' 'bundle' (x,y)-    @--* __'Control.Monad.State.Lazy.State' Monad__--    We can also implement the original @macT@ function as a-    @'Control.Monad.State.Lazy.State'@-    monadic computation. First we must an extra import statement, right after-    the import of "Clash.Prelude":--    @-    import Control.Monad.State-    @--    We can then implement macT as follows:--    @-    macTS (x,y) = do-      acc <- 'Control.Monad.State.Lazy.get'-      'Control.Monad.State.Lazy.put' (acc + x * y)-      return acc-    @--    We can use the 'mealy' function again, although we will have to change-    position of the arguments and result:--    @-    asStateM-      :: 'HiddenClockReset' domain gated synchronous-      => (i -> 'Control.Monad.State.Lazy.State' s o)-      -> s-      -> ('Signal' domain i -> 'Signal' domain o)-    asStateM f i = 'mealy' g i-      where-        g s x = let (o,s') = 'Control.Monad.State.Lazy.runState' (f x) s-                in  (s',o)-    @--    We can then create the complete 'mac' circuit as:--    @-    macS = asStateM macTS 0-    @--}--{- $higher_order-An FIR filter is defined as: the dot-product of a set of filter coefficients and-a window over the input, where the size of the window matches the number-of coefficients.--@-dotp as bs = 'sum' ('zipWith' (*) as bs)--fir coeffs x_t = y_t-  where-    y_t = dotp coeffs xs-    xs  = 'window' x_t--topEntity-  :: 'Clock' System 'Source'-  -> 'Reset' System 'Asynchronous'-  -> 'Signal' System ('Signed' 16)-  -> 'Signal' System ('Signed' 16)-topEntity = exposeClockReset (fir (0 ':>' 1 ':>' 2 ':>' 3 ':>' 'Nil'))-@--Here we can see that, although the CλaSH compiler handles recursive function-definitions poorly, many of the regular patterns that we often encounter in-circuit design are already captured by the higher-order functions that are-present for the 'Vec'tor type.--}--{- $composition_sequential-Given a function @f@ of type:--@-__f__ :: Int -> (Bool, Int) -> (Int, (Int, Bool))-@--When we want to make compositions of @f@ in @g@ using 'mealy', we have to-write:--@-g a b c = (b1,b2,i2)-  where-    (i1,b1) = 'unbundle' ('mealy' f 0 ('bundle' (a,b)))-    (i2,b2) = 'unbundle' ('mealy' f 3 ('bundle' (i1,c)))-@--Why do we need these 'bundle', and 'unbundle' functions you might ask? When we-look at the type of 'mealy':--@-__mealy__ :: (s -> i -> (s,o))-      -> s-      -> ('Signal' i -> 'Signal' o)-@--we see that the resulting function has an input of type @'Signal' i@, and an-output of @'Signal' o@. However, the type of @(a,b)@ in the definition of @g@ is:-@('Signal' Bool, 'Signal' Int)@. And the type of @(i1,b1)@ is of type-@('Signal' Int, 'Signal' Bool)@.--Syntactically, @'Signal' domain (Bool,Int)@ and @('Signal' domain Bool,-'Signal' domain Int)@ are /unequal/.-So we need to make a conversion between the two, that is what 'bundle' and-'unbundle' are for. In the above case 'bundle' gets the type:--@-__bundle__ :: ('Signal' domain Bool, 'Signal' domain Int) -> 'Signal' domain (Bool,Int)-@--and 'unbundle':--@-__unbundle__ :: 'Signal' domain (Int,Bool) -> ('Signal' domain Int, 'Signal' domain Bool)-@--The /true/ types of these two functions are, however:--@-__bundle__   :: 'Bundle' a => 'Unbundled' domain a -> 'Signal' domain a-__unbundle__ :: 'Bundle' a => 'Signal' domain a -> 'Unbundled' domain a-@--'Unbundled' is an <http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl associated type family>-belonging to the 'Bundle' <http://en.wikipedia.org/wiki/Type_class type class>,-which, together with 'bundle' and 'unbundle' defines the isomorphism between a-product type of 'Signal's and a 'Signal' of a product type. That is, while-@(Signal a, Signal b)@ and @Signal (a,b)@ are not equal, they are /isomorphic/-and can be converted from, or to, the other using 'bundle' and 'unbundle'.--Instances of this 'Bundle' type-class are defined as /isomorphisms/ for:--  * All tuples up to and including 62-tuples (GHC limit)-  * The 'Vec'tor type--But they are defined as /identities/ for:--  * All elementary / primitive types such as: 'Bit', 'Bool', @'Signed' n@, etc.--That is:--@-instance 'Bundle' (a,b) where-  type 'Unbundled' domain (a,b) = ('Signal' domain a, 'Signal' domain b)-  bundle   (a,b) = (,) '<$>' a '<*>' b-  unbundle tup   = (fst '<$>' tup, snd '<*>' tup)-@--but,--@-instance 'Bundle' Bool where-  type 'Unbundled'' clk Bool = 'Signal'' clk Bool-  bundle   s = s-  unbundle s = s-@--What you need take away from the above is that a product type (e.g. a tuple) of-'Signal's is not syntactically equal to a 'Signal' of a product type, but that-the functions of the 'Bundle' type class allow easy conversion between the two.--As a final note on this section we also want to mention the 'mealyB' function,-which does the bundling and unbundling for us:--@-mealyB :: ('Bundle' i, 'Bundle' o)-       => (s -> i -> (s,o))-       -> s-       -> ('Unbundled' domain i -> 'Unbundled' domain o)-@--Using 'mealyB' we can define @g@ as:--@-g a b c = (b1,b2,i2)-  where-    (i1,b1) = 'mealyB' f 0 (a,b)-    (i2,b2) = 'mealyB' f 3 (i1,c)-@--The general rule of thumb is: always use 'mealy', unless you do pattern matching-or construction of product types, then use 'mealyB'.--}--{- $annotations #annotations#-'Synthesize' annotations allow us to control hierarchy and naming aspects of the-CλaSH compiler, specifically, they allow us to:--    * Assign names to entities (VHDL) \/ modules ((System)Verilog), and their-      ports.-    * Put generated HDL files of a logical (sub)entity in their own directory.-    * Use cached versions of generated HDL, i.e., prevent recompilation of-      (sub)entities that have not changed since the last run. Caching is based-      on a @.manifest@ which is generated alongside the HDL; deleting this file-      means deleting the cache; changing this file will result in /undefined/-      behaviour.--Functions with a 'Synthesize' annotation do must adhere to the following-restrictions:--    * Although functions with a 'Synthesize' annotation can of course depend-      on functions with another 'Synthesize' annotation, they must not be-      mutually recursive.-    * Functions with a 'Synthesize' annotation must be completely /monomorphic/-      and /first-order/, and cannot have any /non-representable/ arguments or-      result.--Also take the following into account when using 'Synthesize' annotations.--    * The CλaSH compiler is based on the GHC Haskell compiler, and the GHC-      machinery does not understand 'Synthesize' annotations and it might-      subsequently decide to inline those functions. You should therefor also-      add a @{\-\# NOINLINE f \#-\}@ pragma to the functions which you give-      a 'Synthesize' functions.-    * Functions with a 'Synthesize' annotation will not be specialised-      on constants.--Finally, the root module, the module which you pass as an argument to the-CλaSH compiler must either have:--    * A function with a 'Synthesize' annotation.-    * A function called /topEntity/.--You apply 'Synthesize' annotations to functions using an @ANN@ pragma:--@-{\-\# ANN topEntity (Synthesize {t_name = ..., ...  }) \#-\}-topEntity x = ...-@--For example, given the following specification:--@-module Blinker where--import Clash.Prelude-import Clash.Intel.ClockGen--type Dom50 = Dom \"System\" 20000--topEntity-  :: Clock Dom50 Source-  -> Reset Dom50 Asynchronous-  -> Signal Dom50 Bit-  -> Signal Dom50 (BitVector 8)-topEntity clk rst = 'Clash.Signal.exposeClockReset' (\\key1 ->-    let key1R = 'Clash.Prelude.isRising' 1 key1-    in  'Clash.Prelude.mealy' blinkerT (1,False,0) key1R) pllOut rstSync-  where-    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' @@Dom50 (SSymbol @@"altpll50") clk rst-    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeToAsyncReset' pllStable)--blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)-  where-    -- clock frequency = 50e6  (50 MHz)-    -- led update rate = 333e-3 (every 333ms)-    cnt_max = 16650000 -- 50e6 * 333e-3--    cntr' | cntr == cnt_max = 0-          | otherwise       = cntr + 1--    mode' | key1R     = not mode-          | otherwise = mode--    leds' | cntr == 0 = if mode then complement leds-                                else rotateL leds 1-          | otherwise = leds-@--The CλaSH compiler will normally generate the following @blinker_topEntity.vhdl@ file:--@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.blinker_types.all;--entity blinker_topentity is-  port(-- clock-       clk    : in std_logic;-       -- asynchronous reset: active high-       rst    : in std_logic;-       x      : in std_logic;-       result : out std_logic_vector(7 downto 0));-end;--architecture structural of blinker_topentity is- ...-end;-@--However, if we add the following 'Synthesize' annotation in the file:--@-{\-\# ANN topEntity-  ('Synthesize'-    { t_name   = "blinker"-    , t_inputs = [PortName \"CLOCK_50\", PortName \"KEY0\", PortName \"KEY1\"]-    , t_output = PortName \"LED\"-    }) \#-\}-@--The CλaSH compiler will generate the following @blinker.vhdl@ file instead:--@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.blinker_types.all;--entity blinker is-  port(-- clock-       CLOCK_50 : in std_logic;-       -- asynchronous reset: active high-       KEY0     : in std_logic;-       KEY1     : in std_logic;-       LED      : out std_logic_vector(7 downto 0));-end;--architecture structural of blinker is- ...-end;-@--Where we now have:--* A top-level component that is called @blinker@.-* Inputs and outputs that have a /user/-chosen name: @CLOCK_50@, @KEY0@, @KEY1@, @LED@, etc.--See the documentation of 'Synthesize' for the meaning of all its fields.--}--{- $primitives #primitives#-There are times when you already have an existing piece of IP, or there are-times where you need the VHDL to have a specific shape so that the VHDL-synthesis tool can infer a specific component. In these specific cases you can-resort to defining your own VHDL primitives. Actually, most of the primitives-in CλaSH are specified in the same way as you will read about in this section.-There are perhaps 10 (at most) functions which are truly hard-coded into the-CλaSH compiler. You can take a look at the files in-<https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/vhdl>-(or <https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/verilog>-for the Verilog primitives or <https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/systemverilog>-for the SystemVerilog primitives) if you want to know which functions are defined-as \"regular\" primitives. The compiler looks for primitives in four locations:--* The official install location: e.g.-  * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/common@-  * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/commonverilog@-  * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/systemverilog@-  * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/verilog@-  * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/vhdl@-* Directories indicated by a 'Clash.Annotations.Primitive.Primitive' annotation-* The current directory (the location given by @pwd@)-* The include directories specified on the command-line: @-i\<DIR\>@--Where redefined primitives in the current directory or include directories will-overwrite those in the official install location. For now, files containing-primitive definitions must have an @.json@ file-extension.--CλaSH differentiates between two types of primitives, /expression/ primitives-and /declaration/ primitives, corresponding to whether the primitive is a VHDL-/expression/ or a VHDL /declaration/. We will first explore /expression/-primitives, using 'Signed' multiplication ('*') as an example. The-"Clash.Sized.Internal.Signed" module specifies multiplication as follows:--@-(*#) :: 'GHC.TypeLits.KnownNat' n => 'Signed' n -> 'Signed' n -> 'Signed' n-(S a) *# (S b) = fromInteger_INLINE (a * b)-{\-\# NOINLINE (*#) \#-\}-@--For which the VHDL /expression/ primitive is:--@-{ \"BlackBox\" :-  { "name"      : "Clash.Sized.Internal.Signed.*#"-  , "templateE" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"-  }-}-@--The @name@ of the primitive is the /fully qualified/ name of the function you-are creating the primitive for. Because we are creating an /expression/-primitive we define a @template__E__@ field. As the name suggest, it is a VHDL-/template/, meaning that the compiler must fill in the holes heralded by the-tilde (~). Here:--  * @~ARG[1]@ denotes the second argument given to the @(*#)@ function, which-    corresponds to the LHS of the ('*') operator.-  * @~ARG[2]@ denotes the third argument given to the @(*#)@ function, which-    corresponds to the RHS of the ('*') operator.-  * @~LIT[0]@ denotes the first argument given to the @(*#)@ function, with-    the extra condition that it must be a @LIT@eral. If for some reason this-    first argument does not turn out to be a literal then the compiler will-    raise an error. This first arguments corresponds to the \"@'KnownNat' n@\"-    class constraint.--An extensive list with all of the template holes will be given the end of this-section. What we immediately notice is that class constraints are counted as-normal arguments in the primitive definition. This is because these class-constraints are actually represented by ordinary record types, with fields-corresponding to the methods of the type class. In the above case, 'KnownNat'-is actually just like a @newtype@ wrapper for 'Integer'.--The second kind of primitive that we will explore is the /declaration/ primitive.-We will use 'blockRam#' as an example, for which the Haskell/CλaSH code is:--@-import qualified Data.Vector           as V-import           GHC.Stack             (HasCallStack, withFrozenCallStack)--import Clash.Signal.Internal-  (Clock, Signal (..), (.&&.), clockEnable)-import Clash.Sized.Vector     (Vec, toList)-import Clash.XException       (errorX, seqX)---- | blockRAM primitive-blockRam#-  :: HasCallStack-  => 'Clock' dom gated -- ^ Clock to synchronize to-  -> 'Vec' n a         -- ^ Initial content of the BRAM, also-                     -- determines the size, @n@, of the BRAM.-                     ---                     -- __NB__: __MUST__ be a constant.-  -> 'Signal' dom Int  -- ^ Read address /r/-  -> 'Signal' dom Bool -- ^ Write enable-  -> 'Signal' dom Int  -- ^ Write address /w/-  -> 'Signal' dom a    -- ^ Value to write (at address /w/)-  -> 'Signal' dom a-  -- ^ Value of the /blockRAM/ at address /r/ from the previous clock-  -- cycle-blockRam# clk content rd wen = case 'Clash.Signal.Internal.clockEnable' clk of-  Nothing ->-    go (V.fromList ('toList' content))-       (withFrozenCallStack ('errorX' "blockRam: intial value undefined"))-       rd wen-  Just ena ->-    go' (V.fromList ('toList' content))-        (withFrozenCallStack ('errorX' "blockRam: intial value undefined"))-        ena rd (wen '.&&.' ena)-  where-    -- no clock enable-    go !ram o (r :- rs) (e :- en) (w :- wr) (d :- din) =-      let ram' = upd ram e w d-          o'   = ram V.! r-      in  o ``seqX`` o :- go ram' o' rs en wr din-    -- clock enable-    go' !ram o (re :- res) (r :- rs) (e :- en) (w :- wr) (d :- din) =-      let ram' = upd ram e w d-          o'   = if re then ram V.! r else o-      in  o ``seqX`` o :- go' ram' o' res rs en wr din--    upd ram True  addr d = ram V.// [(addr,d)]-    upd ram False _    _ = ram-{\-\# NOINLINE blockRam# \#-\}-@--And for which the /declaration/ primitive is:--@-{ \"BlackBox\" :-  { "name" : "Clash.Explicit.BlockRam.blockRam#"-  , "type" :-"blockRam#-  :: HasCallStack    --       ARG[0]-  => Clock dom gated -- clk,  ARG[1]-  -> Vec n a         -- init, ARG[2]-  -> Signal dom Int  -- rd,   ARG[3]-  -> Signal dom Bool -- wren, ARG[4]-  -> Signal dom Int  -- wr,   ARG[5]-  -> Signal dom a    -- din,  ARG[6]-  -> Signal dom a"-    , "templateD" :-"-- blockRam begin-~GENSYM[~COMPNAME_blockRam][0] : block-  signal ~GENSYM[RAM][1] : ~TYP[2] := ~LIT[2];~IF ~VIVADO ~THEN-  signal ~GENSYM[~RESULT_q][2] : std_logic_vector(~SIZE[~TYP[6]]-1 downto 0);~ELSE-  signal ~SYM[2] : ~TYP[6];~FI-  signal ~GENSYM[rd][3] : integer range 0 to ~LENGTH[~TYP[2]] - 1;-  signal ~GENSYM[wr][4] : integer range 0 to ~LENGTH[~TYP[2]] - 1;~IF ~ISGATED[1] ~THEN-  signal ~GENSYM[clk][5] : std_logic;-  signal ~GENSYM[ce][6] : std_logic;~ELSE ~FI-begin-  ~SYM[3] <= to_integer(~ARG[3])-  -- pragma translate_off-                mod ~LENGTH[~TYP[2]]-  -- pragma translate_on-                ;-  ~SYM[4] <= to_integer(~ARG[5])-  -- pragma translate_off-                mod ~LENGTH[~TYP[2]]-  -- pragma translate_on-                ;-  ~IF ~ISGATED[1] ~THEN-  (~SYM[5],~SYM[6]) <= ~ARG[1];-  ~GENSYM[blockRam_sync][7] : process(~SYM[5])-  begin-    if rising_edge(~SYM[5]) then~IF ~VIVADO ~THEN-      if ~SYM[6] then-        if ~ARG[4] then-          ~SYM[1](~SYM[4]) <= ~TOBV[~ARG[6]][~TYP[6]];-        end if;-        ~SYM[2] <= ~SYM[1](~SYM[3]);-      end if;~ELSE-      if ~ARG[4] and ~SYM[6] then-        ~SYM[1](~SYM[4]) <= ~ARG[6];-      end if;-      if ~SYM[6] then-        ~SYM[2] <= ~SYM[1](~SYM[3]);-      end if;~FI-    end if;-  end process;~ELSE-  ~SYM[7] : process(~ARG[1])-  begin-    if rising_edge(~ARG[1]) then-      if ~ARG[4] then~IF ~VIVADO ~THEN-        ~SYM[1](~SYM[4]) <= ~TOBV[~ARG[6]][~TYP[6]];~ELSE-        ~SYM[1](~SYM[4]) <= ~ARG[6];~FI-      end if;-      ~SYM[2] <= ~SYM[1](~SYM[3]);-    end if;-  end process;~FI~IF ~VIVADO ~THEN-  ~RESULT <= ~FROMBV[~SYM[2]][~TYPO];~ELSE-  ~RESULT <= ~SYM[2];~FI-end block;--- blockRam end"-  }-}-@--Again, the @name@ of the primitive is the fully qualified name of the function-you are creating the primitive for. Because we are creating a /declaration/-primitive we define a @template__D__@ field. Instead of discussing what the-individual template holes mean in the above context, we will instead just give-a general listing of the available template holes:--* @~RESULT@: Signal to which the result of a primitive must be assigned-  to. NB: Only used in a /declaration/ primitive.-* @~ARG[N]@: @(N+1)@'th argument to the function.-* @~LIT[N]@: @(N+1)@'th argument to the function An extra condition that must-  hold is that this @(N+1)@'th argument is an (integer) literal.-* @~TYP[N]@: VHDL type of the @(N+1)@'th argument.-* @~TYPO@: VHDL type of the result.-* @~TYPM[N]@: VHDL type/name/ of the @(N+1)@'th argument; used in /type/-  /qualification/.-* @~TYPM@: VHDL type/name/ of the result; used in /type qualification/.-* @~ERROR[N]@: Error value for the VHDL type of the @(N+1)@'th argument.-* @~ERRORO@: Error value for the VHDL type of the result.-* @~GENSYM[\<NAME\>][N]@: Create a unique name, trying to stay as close to-  the given @\<NAME\>@ as possible. This unique symbol can be referred to in-  other places using @~SYM[N]@.-* @~SYM[N]@: a reference to the unique symbol created by @~GENSYM[\<NAME\>][N]@.-* @~SIGD[\<HOLE\>][N]@: Create a signal declaration, using @\<HOLE\>@ as the name-  of the signal, and the type of the @(N+1)@'th argument.-* @~SIGDO[\<HOLE\>]@: Create a signal declaration, using @\<HOLE\>@ as the name-  of the signal, and the type of the result.-* @~TYPELEM[\<HOLE\>]@: The element type of the vector type represented by @\<HOLE\>@.-  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.-* @~COMPNAME@: The name of the component in which the primitive is instantiated.-* @~LENGTH[\<HOLE\>]@: The vector length of the type represented by @\<HOLE\>@.-* @~DEPTH[\<HOLE\>]@: The tree depth of the type represented by @\<HOLE\>@.-  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.-* @~SIZE[\<HOLE\>]@: The number of bits needed to encode the type represented by @\<HOLE\>@.-  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.-* @~IF \<CONDITION\> ~THEN \<THEN\> ~ELSE \<ELSE\> ~FI@: renders the \<ELSE\>-  part when \<CONDITION\> evaluates to /0/, and renders the \<THEN\> in all-  other cases. Valid @\<CONDITION\>@s are @~LENGTH[\<HOLE\>]@, @~SIZE[\<HOLE\>]@,-  @~DEPTH[\<HOLE\>]@, @~VIVADO@, @~IW64@, @~ISLIT[N]@, @~ISVAR[N], @~ISGATED[N]@,-  @~ISSYNC[N]@, and @~AND[\<HOLE1\>,\<HOLE2\>,..]@.-* @~VIVADO@: /1/ when CλaSH compiler is invoked with the @-fclash-xilinx@ or-  @-fclash-vivado@ flag. To be used with in an @~IF .. ~THEN .. ~ElSE .. ~FI@-  statement.-* @~FROMBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the-  expression in @\<HOLE\>@ is converted to a bit vector (@std_logic_vector@).-  The @\<TYPE\>@ hole indicates the type of the expression and must be either-  @~TYP[N]@, @~TYPO@, or @~TYPELEM[\<HOLE\>]@.-* @~TOBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the-  expression in @\<HOLE\>@, which has a bit vector (@std_logic_vector@) type, is-  converted to type indicated by @\<TYPE\>@. The @\<TYPE\>@ hole indicates the-  must be either @~TYP[N]@, @~TYPO@, or @~TYPELEM[\<HOLE\>]@.-* @~INCLUDENAME[N]@: the generated name of the @N@'th included component.-* @~FILEPATH[\<HOLE\>]@: The argument mentioned in @\<HOLE\>@ is a file which-  must be copied to the location of the generated HDL.-* @~GENERATE@: Verilog: create a /generate/ statement, except when already in-  as /generate/ context.-* @~ENDGENERATE@: Verilog: create an /endgenerate/ statement, except when already-  in a /generate/ context.-* @~ISLIT[N]@: Is the @(N+1)@'th argument to the function a literal.-* @~ISVAR[N]@: Is the @(N+1)@'th argument to the function explicitly not a-  literal-* @~ISGATED[N]@: Is the @(N+1)@'th argument a gated clock, errors when called on-  an argument which is not a 'Clock'.-* @~ISSYNC[N]@: Is the @(N+1)@'th argument a synchronous reset, errors when-  called on an argument which is not a 'Reset'.-* @~AND[\<HOLE1\>,\<HOLE2\>,..]@: Logically /and/ the conditions in the @\<HOLE\>@'s-* @~VARS[N]@: VHDL: Return the variables of the @(N+1)@'th argument.-* @~NAME[N]@: Render the @(N+1)@'th string literal argument as an identifier-  instead of a string literal. Fails when the @(N+1)@'th argument is not a-  string literal.---Some final remarks to end this section: VHDL primitives are there to instruct the-CλaSH compiler to use the given VHDL template, instead of trying to do normal-synthesis. As a consequence you can use constructs inside the Haskell-definitions that are normally not synthesizable by the CλaSH compiler. However,-VHDL primitives do not give us /co-simulation/: where you would be able to-simulate VHDL and Haskell in a /single/ environment. If you still want to-simulate your design in Haskell, you will have to describe, in a cycle- and-bit-accurate way, the behaviour of that (potentially complex) IP you are trying-to include in your design.--Perhaps in the future, someone will figure out how to connect the two simulation-worlds, using e.g. VHDL's foreign function interface VHPI.--}--{- $vprimitives-For those who are interested, the equivalent Verilog primitives are:--@-{ \"BlackBox\" :-  { "name"      : "Clash.Sized.Internal.Signed.*#"-  , "templateE" : "~ARG[1] * ~ARG[2]"-  }-}-@--and--@-{ \"BlackBox\" :-  { "name" : "Clash.Explicit.BlockRam.blockRam#"-  , "type" :-"blockRam#-  :: HasCallStack    -- ARG[0]-  => Clock dom gated -- clk,  ARG[1]-  -> Vec n a         -- init, ARG[2]-  -> Signal dom Int  -- rd,   ARG[3]-  -> Signal dom Bool -- wren, ARG[4]-  -> Signal dom Int  -- wr,   ARG[5]-  -> Signal dom a    -- din,  ARG[6]-  -> Signal dom a"-    , "templateD" :-"// blockRam begin-reg ~TYPO ~GENSYM[RAM][0] [0:~LENGTH[~TYP[2]]-1];-reg ~TYPO ~GENSYM[~RESULT_q][1];-reg ~TYP[2] ~GENSYM[ram_init][2];-integer ~GENSYM[i][3];-initial begin-  ~SYM[2] = ~ARG[2];-  for (~SYM[3]=0; ~SYM[3] < ~LENGTH[~TYP[2]]; ~SYM[3] = ~SYM[3] + 1) begin-    ~SYM[0][~LENGTH[~TYP[2]]-1-~SYM[3]] = ~SYM[2][~SYM[3]*~SIZE[~TYPO]+:~SIZE[~TYPO]];-  end-end-~IF ~ISGATED[1] ~THEN-always @(posedge ~ARG[1][1]) begin : ~GENSYM[~COMPNAME_blockRam][4]~IF ~VIVADO ~THEN-  if (~ARG[1][0]) begin-    if (~ARG[4]) begin-      ~SYM[0][~ARG[5]] <= ~ARG[6];-    end-    ~SYM[1] <= ~SYM[0][~ARG[3]];-  end~ELSE-  if (~ARG[4] & ~ARG[1][0]) begin-    ~SYM[0][~ARG[5]] <= ~ARG[6];-  end-  if (~ARG[1][0]) begin-    ~SYM[1] <= ~SYM[0][~ARG[3]];-  end~FI-end~ELSE-always @(posedge ~ARG[1]) begin : ~SYM[4]-  if (~ARG[4]) begin-    ~SYM[0][~ARG[5]] <= ~ARG[6];-  end-  ~SYM[1] <= ~SYM[0][~ARG[3]];-end~FI-assign ~RESULT = ~SYM[1];-// blockRam end"-  }-}-@---}--{- $svprimitives-And the equivalent SystemVerilog primitives are:--@-{ \"BlackBox\" :-  { "name"      : "Clash.Sized.Internal.Signed.*#"-  , "templateE" : "~ARG[1] * ~ARG[2]"-  }-}-@--and--@-{ \"BlackBox\" :-  { "name" : "Clash.Explicit.BlockRam.blockRam#"-  , "type" :-"blockRam#-  :: HasCallStack    -- ARG[0]-  => Clock dom gated -- clk,  ARG[1]-  -> Vec n a         -- init, ARG[2]-  -> Signal dom Int  -- rd,   ARG[3]-  -> Signal dom Bool -- wren, ARG[4]-  -> Signal dom Int  -- wr,   ARG[5]-  -> Signal dom a    -- din,  ARG[6]-  -> Signal dom a"-    , "templateD" :-"// blockRam begin-~SIGD[~GENSYM[RAM][0]][2];-logic [~SIZE[~TYP[6]]-1:0] ~GENSYM[~RESULT_q][1];-initial begin-  ~SYM[0] = ~LIT[2];-end~IF ~ISGATED[1] ~THEN-always @(posedge ~ARG[1][1]) begin : ~GENSYM[~COMPNAME_blockRam][2]~IF ~VIVADO ~THEN-  if (~ARG[1][0]) begin-    if (~ARG[4]) begin-      ~SYM[0][~ARG[5]] <= ~TOBV[~ARG[6]][~TYP[6]];-    end-    ~SYM[1] <= ~SYM[0][~ARG[3]];-  end~ELSE-  if (~ARG[4] & ~ARG[1][0]) begin-    ~SYM[0][~ARG[5]] <= ~TOBV[~ARG[6]][~TYP[6]];-  end-  if (~ARG[1][0]) begin-    ~SYM[1] <= ~SYM[0][~ARG[3]];-  end~FI-end~ELSE-always @(posedge ~ARG[1]) begin : ~SYM[2]-  if (~ARG[4]) begin-    ~SYM[0][~ARG[5]] <= ~TOBV[~ARG[6]][~TYP[6]];-  end-  ~SYM[1] <= ~SYM[0][~ARG[3]];-end~FI-assign ~RESULT = ~FROMBV[~SYM[1]][~TYP[6]];-// blockRam end"-  }-}-@---}--{- $multiclock #multiclock#-CλaSH supports designs multiple /clock/ (and /reset/) domains, though perhaps in-a slightly limited form. What is possible is:--* Create clock primitives, such as PPLs, which have an accompanying HDL primitive-  (described in later on in this <#primitives tutorial>)-* Explicitly assign clocks to memory primitives.-* Synchronize between differently-clocked parts of your design in a type-safe-  way.--What is /not/ possible is:--* Directly generate a clock signal in module A, and assign this clock signal to-  a memory primitive in module B. For example, the following is not possible:--  @-  type SystemN n = Dom "systemN" n--  pow2Clocks-    :: Clock (SystemN n) Source-    -> Reset (SystemN n) Asynchronous-    -> (Clock (SystemN (16 * n)) Source-       ,Clock (SystemN ( 8 * n)) Source-       ,Clock (SystemN ( 4 * n)) Source-       ,Clock (SystemN ( 2 * n)) Source-       )-  pow2Clocks clk rst = (cnt!3,cnt!2,cnt!1,cnt!0)-    where-      cnt = 'Clash.Explicit.Signal.register' clk rst 0 (cnt + 1)-  @--  As it is not possible to convert the individual bits to a 'Clock'.--  However! What is possible is to do the following:--  @-  pow2Clock'-    :: forall n-     . KnownNat n-    => Clock (SystemN n) Source-    -> Reset (SystemN n) Asynchronous-    -> (Clock (SystemN (16 * n)) Source-       ,Clock (SystemN ( 8 * n)) Source-       ,Clock (SystemN ( 4 * n)) Source-       ,Clock (SystemN ( 2 * n)) Source-       )-  pow2Clocks' clk rst = ('clockGen','clockGen','clockGen','clockGen')-  {\-\# NOINLINE pow2Clocks' \#-\}-  @--  And then create a HDL primitive, as described in later on in-  this <#primitives tutorial>, to implement the desired behaviour in HDL.--What this means is that when CλaSH converts your design to VHDL/(System)Verilog,-you end up with a top-level module/entity with multiple clock and reset ports-for the different clock domains. If you're targeting an FPGA, you can use e.g. a-<https://www.altera.com/literature/ug/ug_altpll.pdf PPL> or-<http://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf MMCM>-to provide the clock signals.--== Building a FIFO synchroniser--This part of the tutorial assumes you know what <https://en.wikipedia.org/wiki/Metastability_in_electronics metastability>-is, and how it can never truly be avoided in any asynchronous circuit. Also-it assumes that you are familiar with the design of synchronizer circuits, and-why a dual flip-flop synchroniser only works for bit-synchronisation and not-word-synchronisation.-The explicitly clocked versions of all synchronous functions and primitives can-be found in "Clash.Explicit.Prelude", which also re-exports the functions in-"Clash.Signal.Explicit". We will use those functions to create a FIFO where-the read and write port are synchronised to different clocks. Below you can find-the code to build the FIFO synchroniser based on the design described in:-<http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf>--We start with enable a few options that will make writing the type-signatures for-our components a bit easier. Instead of importing the standard "Clash.Prelude"-module, we will import the "Clash.Explicit.Prelude" module where all our clocks-and resets must be explicitly routed:--@-module MultiClockFifo where--import Clash.Explicit.Prelude-import Data.Maybe             (isJust)-import Data.Constraint.Nat    (leTrans)-@--Then we'll start with the /heart/ of the FIFO synchroniser, an asynchronous RAM-in the form of 'asyncRam''. It's called an asynchronous RAM because the read-port is not synchronised to any clock (though the write port is). Note that in-CλaSH we don't really have asynchronous logic, there is only combinational and-synchronous logic. As a consequence, we see in the type signature of-'Clash.Explicit.Prelude.asyncRam':--@-__asyncRam__-  :: (Enum addr, HasCallStack)-  => 'Clock' wdom wgated-   -- ^ Clock to which to synchronise the write port of the RAM-  -> 'Clock' rdom rgated-   -- ^ Clock to which the read address signal, __r__, is synchronised-  -> SNat n-  -- ^ Size __n__ of the RAM-  -> Signal rdom addr-  -- ^ Read address __r__-  -> Signal wdom (Maybe (addr, a))-  -- ^ (write address __w__, value to write)-  -> Signal rdom a-   -- ^ Value of the __RAM__ at address __r__-@--that the signal containing the read address __r__ is synchronised to a different-clock. That is, there is __no__ such thing as an @AsyncSignal@ in CλaSH.--We continue by instantiating the 'Clash.Explicit.Prelude.asyncRam':--@-fifoMem wclk rclk addrSize wfull raddr wdataM =-  'Clash.Explicit.Prelude.asyncRam' wclk rclk-            ('pow2SNat' addrSize)-            raddr-            ('mux' wfull (pure Nothing) wdataM)-@--We see that we give it @2^addrSize@ elements, where @addrSize@ is the bit-size-of the address. Also, we only write new values to the RAM when a new write is-requested, indicated by @wdataM@ having a $Just$ value, and the buffer is not-full, indicated by @wfull@.--The next part of the design calculates the read and write address for the-asynchronous RAM, and creates the flags indicating whether the FIFO is full-or empty. The address and flag generator is given in 'mealy' machine style:--@-ptrCompareT addrSize\@SNat flagGen (bin,ptr,flag) (s_ptr,inc) =-    ((bin',ptr',flag')-    ,(flag,addr,ptr))-  where-    -- GRAYSTYLE2 pointer-    bin' = bin + 'boolToBV' (inc && not flag)-    ptr' = (bin' \`shiftR\` 1) \`xor\` bin'-    addr = 'truncateB' bin--    flag' = flagGen ptr' s_ptr-@--It is parametrised in both address size, @addrSize@, and status flag generator,-@flagGen@. It has two inputs, @s_ptr@, the synchronised pointer from the other-clock domain, and @inc@, which indicates we want to perform a write or read of-the FIFO. It creates three outputs: @flag@, the full or empty flag, @addr@, the-read or write address into the RAM, and @ptr@, the Gray-encoded version of the-read or write address which will be synchronised between the two clock domains.--Next follow the initial states of address generators, and the flag generators-for the empty and full flags:--@--- FIFO empty: when next pntr == synchronized wptr or on reset-isEmpty       = (==)-rptrEmptyInit = (0,0,True)---- FIFO full: when next pntr == synchronized {~wptr[addrSize:addrSize-1],wptr[addrSize-2:0]}-isFull :: forall addrSize .-          (2 <= addrSize)-       => 'SNat' addrSize-       -> 'BitVector' (addrSize + 1)-       -> 'BitVector' (addrSize + 1)-       -> Bool-isFull addrSize@SNat ptr s_ptr = case leTrans @1 @2 @addrSize of-  Sub Dict ->-    let a1 = 'SNat' \@(addrSize - 1)-        a2 = 'SNat' \@(addrSize - 2)-    in  ptr == ('complement' ('slice' addrSize a1 s_ptr) '++#' 'slice' a2 d0 s_ptr)--wptrFullInit        = (0,0,False)-@--We create a dual flip-flop synchroniser to be used to synchronise the-Gray-encoded pointers between the two clock domains:--@-ptrSync clk1 clk2 rst2 =-  'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.unsafeSynchronizer' clk1 clk2-@--It uses the 'unsafeSynchroniser' primitive, which is needed to go from one clock-domain to the other. All synchronizers are specified in terms of-'unsafeSynchronizer' (see for example the <src/Clash-Prelude-RAM.html#line-103 source of asyncRam>).-The 'unsafeSynchronizer' primitive is turned into a (bundle of) wire(s) by the-CλaSH compiler, so developers must ensure that it is only used as part of a-proper synchronizer.--Finally we combine all the component in:--@-asyncFIFOSynchronizer-  :: (2 <= addrSize)-  => SNat addrSize-  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@-  -- elements.-  -> 'Clock' wdomain wgated-  -- ^ Clock to which the write port is synchronised-  -> 'Clock' rdomain rgated-  -- ^ Clock to which the read port is synchronised-  -> 'Reset' wdomain synchronous-  -> 'Reset' rdomain synchronous-  -> Signal rdomain Bool-  -- ^ Read request-  -> Signal wdomain (Maybe a)-  -- ^ Element to insert-  -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)-  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)-asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst rinc wdataM =-    (rdata,rempty,wfull)-  where-    s_rptr = dualFlipFlopSynchronizer rclk wclk wrst 0 rptr-    s_wptr = dualFlipFlopSynchronizer wclk rclk rrst 0 wptr--    rdata = fifoMem wclk rclk addrSize wfull raddr-              (liftA2 (,) \<$\> (pure \<$\> waddr) \<*\> wdataM)--    (rempty,raddr,rptr) = 'Clash.Explicit.Prelude.mealyB' rclk rrst (ptrCompareT addrSize isEmpty) rptrEmptyInit-                                 (s_wptr,rinc)--    (wfull,waddr,wptr)  = 'Clash.Explicit.Prelude.mealyB' wclk wrst (ptrCompareT addrSize (isFull addrSize))-                                 wptrFullInit (s_rptr,isJust \<$\> wdataM)-@--where we first specify the synchronisation of the read and the write pointers,-instantiate the asynchronous RAM, and instantiate the read address \/ pointer \/-flag generator and write address \/ pointer \/ flag generator.--Ultimately, the whole file containing our FIFO design will look like this:--@-module MultiClockFifo where--import Clash.Prelude-import Clash.Explicit.Prelude-import Data.Maybe             (isJust)--fifoMem wclk rclk addrSize wfull raddr wdataM =-  'Clash.Explicit.Prelude.asyncRam' wclk rclk-            ('pow2SNat' addrSize)-            raddr-            ('mux' wfull (pure Nothing) wdataM)--ptrCompareT addrSize\@SNat flagGen (bin,ptr,flag) (s_ptr,inc) =-    ((bin',ptr',flag')-    ,(flag,addr,ptr))-  where-    -- GRAYSTYLE2 pointer-    bin' = bin + 'boolToBV' (inc && not flag)-    ptr' = (bin' \`shiftR\` 1) \`xor\` bin'-    addr = 'truncateB' bin--    flag' = flagGen ptr' s_ptr---- FIFO empty: when next pntr == synchronized wptr or on reset-isEmpty       = (==)-rptrEmptyInit = (0,0,True)---- FIFO full: when next pntr == synchronized {~wptr[addrSize:addrSize-1],wptr[addrSize-2:0]}-isFull :: forall addrSize .-          (2 <= addrSize)-       => 'SNat' addrSize-       -> 'BitVector' (addrSize + 1)-       -> 'BitVector' (addrSize + 1)-       -> Bool-isFull addrSize@SNat ptr s_ptr = case leTrans @1 @2 @addrSize of-  Sub Dict ->-    let a1 = 'SNat' \@(addrSize - 1)-        a2 = 'SNat' \@(addrSize - 2)-    in  ptr == ('complement' ('slice' addrSize a1 s_ptr) '++#' 'slice' a2 d0 s_ptr)--wptrFullInit        = (0,0,False)---- Dual flip-flop synchroniser-ptrSync clk1 clk2 rst2 =-  'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.unsafeSynchronizer' clk1 clk2---- Async FIFO synchroniser-asyncFIFOSynchronizer-  :: (2 <= addrSize)-  => SNat addrSize-  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@-  -- elements.-  -> 'Clock' wdomain wgated-  -- ^ Clock to which the write port is synchronised-  -> 'Clock' rdomain rgated-  -- ^ Clock to which the read port is synchronised-  -> 'Reset' wdomain synchronous-  -> 'Reset' rdomain synchronous-  -> Signal rdomain Bool-  -- ^ Read request-  -> Signal wdomain (Maybe a)-  -- ^ Element to insert-  -> (Signal rdomain a, Signal rdomain Bool, Signal wdomain Bool)-  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)-asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst rinc wdataM =-    (rdata,rempty,wfull)-  where-    s_rptr = dualFlipFlopSynchronizer rclk wclk wrst 0 rptr-    s_wptr = dualFlipFlopSynchronizer wclk rclk rrst 0 wptr--    rdata = fifoMem wclk rclk addrSize wfull raddr-              (liftA2 (,) \<$\> (pure \<$\> waddr) \<*\> wdataM)--    (rempty,raddr,rptr) = 'Clash.Explicit.Prelude.mealyB' rclk rrst (ptrCompareT addrSize isEmpty) rptrEmptyInit-                                 (s_wptr,rinc)--    (wfull,waddr,wptr)  = 'Clash.Explicit.Prelude.mealyB' wclk wrst (ptrCompareT addrSize (isFull addrSize))-                                 wptrFullInit (s_rptr,isJust \<$\> wdataM)-@--== Instantiating a FIFO synchroniser--Having finished our FIFO synchroniser it's time to instantiate with concrete-clock domains. Let us assume we have part of our system connected to an ADC-which runs at 20 MHz, and we have created an FFT component running at only 9-MHz. We want to connect part of our design connected to the ADC, and running-at 20 MHz, to part of our design connected to the FFT running at 9 MHz.--We can calculate the clock periods using 'freqCalc':-->>> freqCalc 20e6-50000->>> freqCalc 9e6-111112--We can then create the clock and reset domains:--@-type DomADC = 'Dom \"ADC\" 50000-type DomFFT = 'Dom \"FFT\" 111112-@--and subsequently a 256-space FIFO synchroniser that safely bridges the ADC clock-domain and to the FFT clock domain:--@-adcToFFT-  :: Clock DomADC wgated-  -> Clock DomFFT rgated-  -> Reset DomADC synchronous-  -> Reset DomFFT synchronous-  -> Signal DomFFT Bool-  -> Signal DomADC (Maybe (SFixed 8 8))-  -> (Signal DomFFT (SFixed 8 8), Signal DomFFT Bool, Signal DomADC Bool)-adcToFFT = asyncFIFOSynchronizer d8-@---}--{- $conclusion-For now, this is the end of this tutorial. We will be adding updates over time,-so check back from time to time. For now, we recommend that you continue with-exploring the "Clash.Prelude" module, and get a better understanding of the-capabilities of CλaSH in the process.--}--{- $errorsandsolutions-A list of often encountered errors and their solutions:--* __Type error: Couldn't match expected type @'Signal' (a,b)@ with actual type__-  __@('Signal' a, 'Signal' b)@__:--    Signals of product types and product types (to which tuples belong) of-    signals are __isomorphic__ due to synchronisity principle, but are not-    (structurally) equal. Use the 'bundle' function to convert from a product type-    to the signal type. So if your code which gives the error looks like:--    @-    ... = f a b (c,d)-    @--    add the 'bundle'' function like so:--    @-    ... = f a b ('bundle' (c,d))-    @--    Product types supported by 'bundle' are:--    * All tuples up to and including 62-tuples (GHC limit)-    * The 'Vec'tor type--* __Type error: Couldn't match expected type @('Signal' domain a, 'Signal' domain b)@ with__-  __ actual type @'Signal' domain (a,b)@__:--    Product types (to which tuples belong) of signals and signals of product-    types are __isomorphic__ due to synchronicity principle, but are not-    (structurally) equal. Use the 'unbundle' function to convert from a signal-    type to the product type. So if your code which gives the error looks like:--    @-    (c,d) = f a b-    @--    add the 'unbundle' function like so:--    @-    (c,d) = 'unbundle' (f a b)-    @--    Product types supported by 'unbundle' are:--    * All tuples up to and including 62-tuples (GHC limit)-    * The 'Vec'tor type--* __Clash.Netlist(..): Not in normal form: \<REASON\>: \<EXPR\>__:--    A function could not be transformed into the expected normal form. This-    usually means one of the following:--    * The @topEntity@ has residual polymorphism.-    * The @topEntity@ has higher-order arguments, or a higher-order result.-    * You are using types which cannot be represented in hardware.--    The solution for all the above listed reasons is quite simple: remove them.-    That is, make sure that the @topEntity@ is completely monomorphic and-    first-order. Also remove any variables and constants/literals that have a-    non-representable type, see <#unsupported Unsupported Haskell features> to-    find out which types are not representable.--* __Clash.Normalize(94): Expr belonging to bndr: \<FUNCTION\> remains__-  __recursive after normalization__:--    * If you actually wrote a recursive function, rewrite it to a non-recursive-      one using e.g. one of the higher-order functions in "Clash.Sized.Vector" :-)--    * You defined a recursively defined value, but left it polymorphic:--    @-    topEntity x y = acc-      where-        acc = 'register' 3 (acc + x * y)-    @--    The above function, works for any number-like type. This means that @acc@ is-    a recursively defined __polymorphic__ value. Adding a monomorphic type-    annotation makes the error go away:--    @-    topEntity-      :: 'SystemClockReset'-      => 'Signal' 'System' ('Signed' 8)-      -> 'Signal' 'System' ('Signed' 8)-      -> 'Signal' 'System' ('Signed' 8)-    topEntity x y = acc-      where-        acc = 'register' 3 (acc + x * y)-    @--* __Clash.Normalize.Transformations(155): InlineNonRep: \<FUNCTION\> already__-  __inlined 100 times in:\<FUNCTION\>, \<TYPE\>__:--    You left the @topEntity@ function polymorphic or higher-order: use-    @:t topEntity@ to check if the type is indeed polymorphic or higher-order.-    If it is, add a monomorphic type signature, and / or supply higher-order-    arguments.--*  __\<*** Exception: \<\<loop\>\>__ or "blinking cursor"--    You are using value-recursion, but one of the 'Vec'tor functions that you-    are using is too /strict/ in one of the recursive arguments. For example:--    @-    -- Bubble sort for 1 iteration-    sortV xs = 'map' fst sorted ':<' (snd ('last' sorted))-     where-       lefts  = 'head' xs :> 'map' snd ('init' sorted)-       rights = 'tail' xs-       sorted = 'zipWith' compareSwapL lefts rights--    -- Compare and swap-    compareSwapL a b = if a < b then (a,b)-                                else (b,a)-    @--    Will not terminate because 'zipWith' is too strict in its second argument.--    In this case, adding 'lazyV' on 'zipWith's second argument:--    @-    sortVL xs = 'map' fst sorted ':<' (snd ('last' sorted))-     where-       lefts  = 'head' xs :> map snd ('init' sorted)-       rights = 'tail' xs-       sorted = 'zipWith' compareSwapL ('lazyV' lefts) rights-    @--    Results in a successful computation:--    >>> sortVL (4 :> 1 :> 2 :> 3 :> Nil)-    <1,2,3,4>--}--{- $limitations #limitations#-Here is a list of Haskell features for which the CλaSH compiler has only-/limited/ support (for now):--* __Recursively defined functions__--    At first hand, it seems rather bad that a compiler for a functional language-    cannot synthesize recursively defined functions to circuits. However, when-    viewing your functions as a /structural/ specification of a circuit, this-    /feature/ of the CλaSH compiler makes sense. Also, only certain types of-    recursion are considered non-synthesisable; recursively defined values are-    for example synthesisable: they are (often) synthesized to feedback loops.--    Let us distinguish between three variants of recursion:--    * __Dynamic data-dependent recursion__--        As demonstrated in this definition of a function that calculates the-        n'th Fibbonacci number:--        @-        fibR 0 = 0-        fibR 1 = 1-        fibR n = fibR (n-1) + fibR (n-2)-        @--        To get the first 10 numbers, we do the following:--        >>> import qualified Data.List as L-        >>> L.map fibR [0..9]-        [0,1,1,2,3,5,8,13,21,34]--        The @fibR@ function is not synthesizable by the CλaSH compiler, because,-        when we take a /structural/ view, @fibR@ describes an infinitely deep-        structure.--        In principal, descriptions like the above could be synthesized to a-        circuit, but it would have to be a /sequential/ circuit. Where the most-        general synthesis would then require a stack. Such a synthesis approach-        is also known as /behavioural/ synthesis, something which the CλaSH-        compiler simply does not do. One reason that CλaSH does not do this is-        because it does not fit the paradigm that only functions working on-        values of type 'Signal' result in sequential circuits, and all other-        (non higher-order) functions result in combinational circuits. This-        paradigm gives the designer the most straightforward mapping from the-        original Haskell description to generated circuit, and thus the greatest-        control over the eventual size of the circuit and longest propagation-        delay.--    * __Value-recursion__--        As demonstrated in this definition of a function that calculates the-        n'th Fibbonaci number on the n'th clock cycle:--        @-        fibS = r-          where r = 'register' 0 r + 'register' 0 ('register' 1 r)-        @--        To get the first 10 numbers, we do the following:--        >>> sampleN @Source @Asynchronous 10 fibS-        [0,1,1,2,3,5,8,13,21,34]--        Unlike the @fibR@ function, the above @fibS@ function /is/ synthesisable-        by the CλaSH compiler. Where the recursively defined (non-function)-        value /r/ is synthesized to a feedback loop containing three registers-        and one adder.--        Note that not all recursively defined values result in a feedback loop.-        An example that uses recursively defined values which does not result-        in a feedback loop is the following function that performs one iteration-        of bubble sort:--        @-        sortV xs = 'map' fst sorted :< (snd ('last' sorted))-         where-           lefts  = 'head' xs :> 'map' snd ('init' sorted)-           rights = 'tail' xs-           sorted = 'zipWith' compareSwapL lefts rights-        @--        Where we can clearly see that 'lefts' and 'sorted' are defined in terms-        of each other. Also the above @sortV@ function /is/ synthesisable.--    * __Static/Structure-dependent recursion__--        Static, or, structure-dependent recursion is a rather /vague/ concept.-        What we mean by this concept are recursive definitions where a user can-        sensibly imagine that the recursive definition can be completely-        unfolded (all recursion is eliminated) at compile-time in a finite-        amount of time.--        Such definitions would e.g. be:--        @-        mapV :: (a -> b) -> Vec n a -> Vec n b-        mapV _ Nil         = Nil-        mapV f (Cons x xs) = Cons (f x) (mapV f xs)--        topEntity :: Vec 4 Int -> Vec 4 Int-        topEntity = mapV (+1)-        @--        Where one can imagine that a compiler can unroll the definition of-        @mapV@ four times, knowing that the @topEntity@ function applies @mapV@-        to a 'Vec' of length 4. Sadly, the compile-time evaluation mechanisms in-        the CλaSH compiler are very poor, and a user-defined function such as-        the @mapV@ function defined above, is /currently/ not synthesisable.-        We /do/ plan to add support for this in the future. In the mean time,-        this poor support for user-defined recursive functions is amortized by-        the fact that the CλaSH compiler has built-in support for the-        higher-order functions defined in "Clash.Sized.Vector". Most regular-        design patterns often encountered in circuit design are captured by the-        higher-order functions in "Clash.Sized.Vector".--* __Recursive datatypes__--    The CλaSH compiler needs to be able to determine a bit-size for any value-    that will be represented in the eventual circuit. More specifically, we need-    to know the maximum number of bits needed to represent a value. While this-    is trivial for values of the elementary types, sum types, and product types,-    putting a fixed upper bound on recursive types is not (always) feasible.-    This means that the ubiquitous list type is unsupported! The only recursive-    type that is currently supported by the CλaSH compiler is the 'Vec'tor type,-    for which the compiler has hard-coded knowledge.--    For \"easy\" 'Vec'tor literals you should use Template Haskell splices and-    the 'listToVecTH' /meta/-function that as we have seen earlier in this tutorial.--* __GADT pattern matching__--    While pattern matching for regular ADTs is supported, pattern matching for-    GADTs is __not__. The constructors 'Cons' and 'Nil' of the 'Vec'tor type,-    which is also a GADT, are __no__ exception! However, you can use the-    convenient ':>' pattern synonym.--* __Floating point types__--    There is no support for the 'Float' and 'Double' types, if you need numbers-    with a /fractional/ part you can use the 'Fixed' point type.--    As to why there is no support for these floating point types:--        1.  In order to achieve reasonable operating frequencies, arithmetic-            circuits for floating point data types must be pipelined.-        2.  Haskell's primitive arithmetic operators on floating point data types,-            such as 'plusFloat#'--            @-            __plusFloat#__ :: 'Float#' -> 'Float#' -> 'Float#'-            @--            which underlie @'Float'@'s 'Num' instance, must be implemented as-            purely combinational circuits according to their type. Remember,-            sequential circuits operate on values of type \"@'Signal' a@\".--    Although it is possible to implement purely combinational (not pipelined)-    arithmetic circuits for floating point data types, the circuit would be-    unreasonable slow. And so, without synthesis possibilities for the basic-    arithmetic operations, there is no point in supporting the floating point-    data types.--* __Haskell primitive types__--    Only the following primitive Haskell types are supported:--        * 'Integer'-        * 'Int'-        * 'Int8'-        * 'Int16'-        * 'Int32'-        * 'Int64' (not available when compiling with @-fclash-intwidth=32@ on a 64-bit machine)-        * 'Word'-        * 'Word8'-        * 'Word16'-        * 'Word32'-        * 'Word64' (not available when compiling with @-fclash-intwidth=32@ on a 64-bit machine)-        * 'Char'--    There are several aspects of which you should take note:--        *   'Int' and 'Word' are represented by the same number of bits as is-            native for the architecture of the computer on which the CλaSH-            compiler is executed. This means that if you are working on a 64-bit-            machine, 'Int' and 'Word' will be 64-bit. This might be problematic-            when you are working in a team, and one designer has a 32-bit-            machine, and the other has a 64-bit machine. In general, you should-            be avoiding 'Int' in such cases, but as a band-aid solution, you can-            force the CλaSH compiler to use a specific bit-width for `Int` and-            `Word` using the @-fclash-intwidth=N@ flag, where /N/ must either be-            /32/ or /64/.--        *   When you use the @-fclash-intwidth=32@ flag on a /64-bit/ machine,-            the 'Word64' and 'Int64' types /cannot/ be translated. This-            restriction does /not/ apply to the other three combinations of-            @-fclash-intwidth@ flag and machine type.--        *   The translation of 'Integer' is not meaning-preserving. 'Integer' in-            Haskell is an arbitrary precision integer, something that cannot-            be represented in a statically known number of bits. In the CλaSH-            compiler, we chose to represent 'Integer' by the same number of bits-            as we do for 'Int' and 'Word'. As you have read in a previous-            bullet point, this number of bits is either 32 or 64, depending on-            the architecture of the machine the CλaSH compiler is running on, or-            the setting of the @-fclash-intwidth@ flag.--            Consequently, you should use `Integer` with due diligence; be-            especially careful when using `fromIntegral` as it does a conversion-            via 'Integer'. For example:--                > signedToUnsigned :: Signed 128 -> Unsigned 128-                > signedToUnsigned = fromIntegral--            can either lose the top 64 or 96 bits depending on whether 'Integer'-            is represented by 64 or 32 bits. Instead, when doing such conversions,-            you should use 'bitCoerce':--                > signedToUnsigned :: Signed 128 -> Unsigned 128-                > signedToUnsigned = bitCoerce--* __Side-effects: 'IO', 'ST', etc.__--    There is no support for side-effecting computations such as those in the-    'IO' or 'ST' monad. There is also no support for Haskell's-    <http://www.haskell.org/haskellwiki/Foreign_Function_Interface FFI>.--}--{- $vslava-In Haskell land the most well-known way of describing digital circuits is the-Lava family of languages:--* <http://hackage.haskell.org/package/chalmers-lava2000 Chalmers Lava>-* <http://hackage.haskell.org/package/xilinx-lava Xilinx Lava>-* <http://hackage.haskell.org/package/york-lava York Lava>-* <http://hackage.haskell.org/package/kansas-lava Kansas Lava>--The big difference between CλaSH and Lava is that CλaSH uses a \"standard\"-compiler (static analysis) approach towards synthesis, where Lava is an-embedded domain specific language. One downside of static analysis vs. the-embedded language approach is already clearly visible: synthesis of recursive-descriptions does not come for \"free\". This will be implemented in CλaSH in-due time, but that doesn't help the circuit designer right now. As already-mentioned earlier, the poor support for recursive functions is amortized by-the built-in support for the higher-order in "Clash.Sized.Vector".--The big upside of CλaSH and its static analysis approach is that CλaSH can-do synthesis of \"normal\" functions: there is no forced encasing datatype (often-called /Signal/ in Lava) on all the arguments and results of a synthesizable-function. This enables the following features not available to Lava:--* Automatic synthesis for user-defined ADTs-* Synthesis of all choice constructs (pattern matching, guards, etc.)-* 'Applicative' instance for the 'Signal' type-* Working with \"normal\" functions permits the use of e.g. the-  'Control.Monad.State.Lazy.State' monad to describe the functionality of a-  circuit.--Although there are Lava alternatives to some of the above features (e.g.-first-class patterns to replace pattern matching) they are not as \"beautiful\"-and / or easy to use as the standard Haskell features.--}--{- $migration--* The top name in the module hierarchy has changed from \"@CLaSH@\" to-  \"@Clash@\".--* There is no longer any distinction between @Signal@ and @Signal'@, there is-  only 'Signal' which has a /domain/ and /value/ type variable.--    @-    data Signal (dom :: Domain) a-    @--* The \"@Clash.Prelude.Explicit@\" module has been removed because all 'Signal's-  have a /domain/ annotation now. There is a "Clash.Explicit.Prelude" module,-  but it serves a different purpose: it exports a prelude where all synchronous-  components have an explicit clock (and reset) value; "Clash.Prelude" exports-  synchronous components with <Clash-Signal.html#hiddenclockandreset hidden clock and reset> arguments.-  Note that "Clash.Prelude" and "Clash.Explicit.Prelude" have overlapping-  definitions, meaning you must use /qualified/ imports to disambiguate.--* All synchronous components have clock and reset arguments now, they appear as-  <Clash-Signal.html#hiddenclockandreset hidden> arguments when you use-  "Clash.Prelude", and as normal arguments when you use "Clash.Explicit.Prelude".--* HDL Testbench generation is no longer predicated on the existence of a-  top-level /testInput/ and /expectedOutput/ function. Instead, top-level functions-  called /testBench/ are now picked up as the entry-point for HDL test benches.-  Alternatively you can use a 'Clash.Annotations.TestBench' /ANN/ pragma.--* 'Clash.Annotations.TopEntity' annotations have received a complete overhaul,-  and you should just rewrite them from scratch. Additionally, designs can-  contain multiple 'Clash.Annotations.Synthesize' to split generated HDL over-  multiple output directories.--* With the overhaul of 'Clash.Annotations.TopEntity' annotations and the-  introduction of explicit clock and reset arguments, PLLs and other clock-  sources are now regular Clash functions such as those found in-  "Clash.Intel.ClockGen" and "Clash.Xilinx.ClockGen".---=== Examples--==== FIR filter--FIR filter in Clash 0.7:--@-module FIR where--import CLaSH.Prelude--dotp :: SaturatingNum a-     => Vec (n + 1) a-     -> Vec (n + 1) a-     -> a-dotp as bs = fold boundedPlus (zipWith boundedMult as bs)--fir :: (Default a, KnownNat n, SaturatingNum a)-    => Vec (n + 1) a -> Signal a -> Signal a-fir coeffs x_t = y_t-  where-    y_t = dotp coeffs \<$\> bundle xs-    xs  = window x_t--topEntity :: Signal (Signed 16) -> Signal (Signed 16)-topEntity = fir (2:>3:>(-2):>8:>Nil)--testInput :: Signal (Signed 16)-testInput = stimuliGenerator (2:>3:>(-2):>8:>Nil)--expectedOutput :: Signal (Signed 16) -> Signal Bool-expectedOutput = outputVerifier (4:>12:>1:>20:>Nil)-@--FIR filter in current version:--@-module FIR where--import Clash.Prelude-import Clash.Explicit.Testbench--dotp :: SaturatingNum a-     => Vec (n + 1) a-     -> Vec (n + 1) a-     -> a-dotp as bs = fold boundedPlus (zipWith boundedMult as bs)--fir-  :: (Default a, KnownNat n, SaturatingNum a, HiddenClockReset domain gated synchronous)-  => Vec (n + 1) a -> Signal domain a -> Signal domain a-fir coeffs x_t = y_t-  where-    y_t = dotp coeffs \<$\> bundle xs-    xs  = window x_t--topEntity-  :: Clock  System Source-  -> Reset  System Asynchronous-  -> Signal System (Signed 16)-  -> Signal System (Signed 16)-topEntity = exposeClockReset (fir (2:>3:>(-2):>8:>Nil))-{\-\# NOINLINE topEntity \#-\}--testBench :: Signal System Bool-testBench = done-  where-    testInput      = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)-    expectedOutput = outputVerifier clk rst (4:>12:>1:>20:>Nil)-    done           = expectedOutput (topEntity clk rst testInput)-    clk            = tbSystemClockGen (not \<$\> done)-    rst            = systemResetGen-@--==== Blinker circuit--Blinker circuit in Clash 0.7:--@-module Blinker where--import CLaSH.Prelude--{\-\# ANN topEntity-  (defTop-    { t_name     = "blinker"-    , t_inputs   = [\"KEY1\"]-    , t_outputs  = [\"LED\"]-    , t_extraIn  = [ (\"CLOCK_50\", 1)-                   , (\"KEY0\"    , 1)-                   ]-    , t_clocks   = [ altpll "altpll50" "CLOCK_50(0)" "not KEY0(0)" ]-    }) \#-\}-topEntity :: Signal Bit -> Signal (BitVector 8)-topEntity key1 = leds-  where-    key1R = isRising 1 key1-    leds  = mealy blinkerT (1,False,0) key1R--blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)-  where-    -- clock frequency = 50e6  (50 MHz)-    -- led update rate = 333e-3 (every 333ms)-    cnt_max = 16650000 -- 50e6 * 333e-3--    cntr' | cntr == cnt_max = 0-          | otherwise       = cntr + 1--    mode' | key1R     = not mode-          | otherwise = mode--    leds' | cntr == 0 = if mode then complement leds-                                else rotateL leds 1-          | otherwise = leds-@--Blinker circuit in the current version:--@-module Blinker where--import Clash.Prelude-import Clash.Intel.ClockGen--type Dom50 = Dom \"System\" 20000--{\-\# ANN topEntity-  (Synthesize-    { t_name   = "blinker"-    , t_inputs = [ PortName \"CLOCK_50\"-                 , PortName \"KEY0\"-                 , PortName \"KEY1\"-                 ]-    , t_output = PortName \"LED\"-    }) \#-\}-topEntity-  :: Clock Dom50 Source-  -> Reset Dom50 Asynchronous-  -> Signal Dom50 Bit-  -> Signal Dom50 (BitVector 8)-topEntity clk rst =-    exposeClockReset (mealy blinkerT (1,False,0) . isRising 1) pllOut rstSync-  where-    (pllOut,pllStable) = altpll \@Dom50 (SSymbol \@ "altpll50") clk rst-    rstSync            = resetSynchronizer pllOut (unsafeToAsyncReset pllStable)--blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)-  where-    -- clock frequency = 50e6  (50 MHz)-    -- led update rate = 333e-3 (every 333ms)-    cnt_max = 16650000 -- 50e6 * 333e-3--    cntr' | cntr == cnt_max = 0-          | otherwise       = cntr + 1--    mode' | key1R     = not mode-          | otherwise = mode--    leds' | cntr == 0 = if mode then complement leds-                                else rotateL leds 1-          | otherwise = leds-@-+              2017-2019, Myrtle Software Ltd+              2017     , QBayLogic, Google Inc.+Licence   : Creative Commons 4.0 (CC BY 4.0) (http://creativecommons.org/licenses/by/4.0/)+-}++{-# LANGUAGE NoImplicitPrelude, MagicHash #-}+{-# OPTIONS_GHC -fno-warn-unused-imports #-}++module Clash.Tutorial (+  -- * Introduction+  -- $introduction++  -- * Install Clash+  -- $installation++  -- * Working with this tutorial+  -- $working++  -- * Your first circuit+  -- $mac_example++  -- *** Sequential circuit+  -- $mac2++  -- *** Generating VHDL+  -- $mac3++  -- *** Circuit testbench+  -- $mac4++  -- *** Generating Verilog and SystemVerilog+  -- $mac5++  -- *** Alternative specifications+  -- $mac6++  -- * Higher-order functions+  -- $higher_order++  -- * Composition of sequential circuits+  -- $composition_sequential++  -- * Synthesize annotations: controlling the VHDL\/(System)Verilog generation.+  -- $annotations++  -- * Multiple clock domains+  -- $multiclock++  -- * Advanced: Primitives+  -- $primitives++  -- *** Verilog primitives+  -- $vprimitives++  -- *** SystemVerilog primitives+  -- $svprimitives++  -- * Conclusion+  -- $conclusion++  -- * Troubleshooting+  -- $errorsandsolutions++  -- * Limitations of Clash+  -- $limitations++  -- * Clash vs Lava+  -- $vslava++  -- * Migration guide from Clash 0.99+  -- $migration+  )+where++import Clash.Prelude+import Clash.Explicit.Testbench+import Clash.XException (NFDataX)+import Control.Monad.ST+import Data.Array+import Data.Char+import Data.Int+import GHC.Prim+import GHC.TypeLits+import GHC.Word+import Data.Default.Class++{- $setup+>>> :set -XTemplateHaskell -XDataKinds -XConstraintKinds -XTypeApplications+>>> :{+let ma :: Num a => a -> (a, a) -> a+    ma acc (x,y) = acc + x * y+:}++>>> :{+let macT :: Num a => a -> (a,a) -> (a,a)+    macT acc (x,y) = (acc',o)+       where+         acc' = ma acc (x,y)+         o    = acc+:}++>>> :set -XFlexibleContexts+>>> :set -fplugin GHC.TypeLits.Normalise+>>> let compareSwapL a b = if a < b then (a,b) else (b,a)+>>> :{+let sortV xs = map fst sorted :< (snd (last sorted))+      where+        lefts  = head xs :> map snd (init sorted)+        rights = tail xs+        sorted = zipWith compareSwapL lefts rights+:}++>>> :{+let sortVL xs = map fst sorted :< (snd (last sorted))+      where+        lefts  = head xs :> map snd (init sorted)+        rights = tail xs+        sorted = zipWith compareSwapL (lazyV lefts) rights+:}++>>> let mac = mealy macT 0+>>> :{+topEntity+  :: Clock System+  -> Reset System+  -> Enable System+  -> Signal System (Signed 9, Signed 9)+  -> Signal System (Signed 9)+topEntity = exposeClockResetEnable mac+:}++>>> :{+let testBench :: Signal System Bool+    testBench = done+      where+        testInput      = stimuliGenerator clk rst $(listToVecTH [(1,1) :: (Signed 9,Signed 9),(2,2),(3,3),(4,4)])+        expectedOutput = outputVerifier' clk rst $(listToVecTH [0 :: Signed 9,1,5,14,14,14,14])+        done           = expectedOutput (topEntity clk rst enableGen testInput)+        clk            = tbSystemClockGen (not <$> done)+        rst            = systemResetGen+:}++>>> :{+let fibR :: Unsigned 64 -> Unsigned 64+    fibR 0 = 0+    fibR 1 = 1+    fibR n = fibR (n-1) + fibR (n-2)+:}++>>> :{+let fibS :: SystemClockResetEnable => Signal System (Unsigned 64)+    fibS = r+      where r = register 0 r + register 0 (register 1 r)+:}++-}++{- $introduction+Clash is a functional hardware description language that borrows both its syntax+and semantics from the functional programming language Haskell. It provides a+familiar structural design approach to both combination and synchronous+sequential circuits. The Clash compiler transforms these high-level descriptions+to low-level synthesizable VHDL, Verilog, or SystemVerilog.++Features of Clash:++  * Strongly typed, but with a very high degree of type inference, enabling+    both safe and fast prototyping using concise descriptions.+  * Interactive REPL: load your designs in an interpreter and easily test all+    your component without needing to setup a test bench.+  * Compile your designs for fast simulation.+  * Higher-order functions, in combination with type inference, result in+    designs that are fully parametric by default.+  * Synchronous sequential circuit design based on streams of values, called+    @Signal@s, lead to natural descriptions of feedback loops.+  * Multiple clock domains, with type safe clock domain crossing.+  * Template language for introducing new VHDL/(System)Verilog primitives.++Although we say that Clash borrows the semantics of Haskell, that statement+should be taken with a grain of salt. What we mean to say is that the Clash+compiler views a circuit description as /structural/ description. This means,+in an academic handwavy way, that every function denotes a component and every+function application denotes an instantiation of said component. Now, this has+consequences on how we view /recursively/ defined functions: structurally, a+recursively defined function would denote an /infinitely/ deep / structured+component, something that cannot be turned into an actual circuit+(See also <#limitations Limitations of Clash>).++On the other hand, Haskell's by-default non-strict evaluation works very well+for the simulation of the feedback loops, which are ubiquitous in digital+circuits. That is, when we take our structural view to circuit descriptions,+value-recursion corresponds directly to a feedback loop:++@+counter = s+  where+    s = 'register' 0 (s + 1)+@++The above definition, which uses value-recursion, /can/ be synthesized to a+circuit by the Clash compiler.++Over time, you will get a better feeling for the consequences of taking a+/structural/ view on circuit descriptions. What is always important to+remember is that every applied functions results in an instantiated component,+and also that the compiler will /never/ infer / invent more logic than what is+specified in the circuit description.++With that out of the way, let us continue with installing Clash and building+our first circuit.+-}++{- $installation+For installation instructions, see <https://clash-lang.org/install/ clash-lang.org/install/>.+-}++{- $working+This tutorial can be followed best whilst having the Clash interpreter running+at the same time. If you followed the installation instructions, you already+know how to start the Clash compiler in interpretive mode:++@+clash.clashi  # When installed from source, use 'clashi'+@++For those familiar with Haskell/GHC, this is indeed just @GHCi@, with three+added commands (@:vhdl@, @:verilog@, and @:systemverilog@). You can load files+into the interpreter using the @:l \<FILENAME\>@ command. Now, depending on your+choice in editor, the following @edit-load-run@ cycle probably work best for you:++  * __Commandline (e.g. emacs, vim):__++      * You can run system commands using @:!@, for example @:! touch \<FILENAME\>@+      * Set the /editor/ mode to your favourite editor using: @:set editor \<EDITOR\>@+      * You can load files using @:l@ as noted above.+      * You can go into /editor/ mode using: @:e@+      * Leave the editor mode by quitting the editor (e.g. @:wq@ in @vim@)++  * __GUI (e.g. SublimeText, Notepad++):__++      * Just create new files in your editor.+      * Load the files using @:l@ as noted above.+      * Once a file has been edited and saved, type @:r@ to reload the files in+        the interpreter++You are of course free to deviate from these suggestions as you see fit :-) It+is just recommended that you have the Clash interpreter open during this+tutorial.+-}++{- $mac_example+The very first circuit that we will build is the \"classic\" multiply-and-accumulate+(MAC) circuit. This circuit is as simple as it sounds, it multiplies its inputs+and accumulates them. Before we describe any logic, we must first create the+file we will be working on and input some preliminaries:++* Create the file:++    @+    MAC.hs+    @++* Write on the first line the module header:++    @+    module MAC where+    @++    Module names must always start with a __C__apital letter. Also make sure that+    the file name corresponds to the module name.++* Add the import statement for the Clash prelude library:++    @+    import Clash.Prelude+    @++    This imports all the necessary functions and datatypes for circuit description.++We can now finally start describing the logic of our circuit, starting with just+the multiplication and addition:++@+ma acc (x, y) = acc + x * y+@++The circuit we just wrote is a combinational circuit: no registers are inserted+(you describe explicitly where Clash will insert registers, as we'll later see). We usually+refer to circuits as /functions/, similar to programming languages such as C,+Python, or Haskell. In this case, the function we just defined is called @ma@.+Its first argument is @acc@, its second is @(x, y)@ - a composite type called a+tuple. This component is "unpacked", and its first element is called @x@, its+second @y@. Everything to the right of the equals symbol is @ma@'s+result.+If you followed the instructions of running the interpreter side-by-side, you+can already test this function:++>>> ma 4 (8, 9)+76+>>> ma 2 (3, 4)+14++We can also examine the inferred type of @ma@ in the interpreter:++>>> :t ma+ma :: Num a => a -> (a, a) -> a++You should read this as follows:++ * __@ma ::@__, @ma@ is of type..++ * __@Num a@__, there is some type called @a@ that is a @'Num'@. Examples of+   instances of @'Num'@ are @'Int'@, @'Signed' 16@, @'Index' 32@, and @'Float'@.++ * __@a@__, @ma@'s first argument is of type @a@++ * __@(a, a)@__, @ma@'s second argument is of type @(a, a)@++ * __@a@__, @ma@'s result is of type @a@++Note that @ma@ therefore works on multiple types! The only condition we+imposed is that @a@ should be a @'Num'@ber type. In Clash this means it should+support the operations @'Prelude.+'@, @'Prelude.-'@, @'Prelude.*'@, and some+others. Indeed, this is why Clash adds the constraint in the first place: the+definition of @ma@ uses @+@ and @*@. Whenever a function works over multiple+types, we call it /polymorphic/ ("poly" meaning "many", "morphic" meaning+"forms"). While powerful, its not clear how Clash should synthesize this as+numbers come in a great variety in (bit)sizes. We will later see how to use this+function in a /monomorphic/ manner.++Talking about /types/ also brings us to one of the most important parts of this+tutorial: /types/ and /synchronous sequential logic/. Especially how we can+always determine, through the types of a specification, if it describes+combinational logic or (synchronous) sequential logic. We do this by examining+the definition of one of the sequential primitives, the @'register'@ function:++@+register+     ( 'HiddenClockResetEnable' dom dom+     , 'Clash.XException.NFDataX' a )+  => a+  -> 'Signal' dom a+  -> 'Signal' dom a+register i s = ...+@++Where we see that the second argument and the result are not just of the+/polymorphic/ @a@ type, but of the type: @'Signal' dom a@. All (synchronous)+sequential circuits work on values of type @'Signal' dom a@. Combinational+circuits always work on values of, well, not of type @'Signal' dom a@. A 'Signal'+is an (infinite) list of samples, where the samples correspond to the values+of the 'Signal' at discrete, consecutive, ticks of the /clock/. All (sequential)+components in the circuit are synchronized to this global /clock/. For the+rest of this tutorial, and probably at any moment where you will be working with+Clash, you should probably not actively think about 'Signal's as infinite lists+of samples, but just as values that are manipulated by sequential circuits. To+make this even easier, it actually not possible to manipulate the underlying+representation directly: you can only modify 'Signal' values through a set of+primitives such as the 'register' function above.++Now, let us get back to the functionality of the 'register' function: it is+a simple <https://en.wikipedia.org/wiki/Flip-flop_(electronics) latch> that+only changes state at the tick of the global /clock/, and+it has an initial value @a@ which is its output at time 0. We can further+examine the 'register' function by taking a look at the first 4 samples of the+'register' functions applied to a constant signal with the value 8:++>>> sampleN @System 4 (register 0 (pure (8 :: Signed 8)))+[0,0,8,8]++Where we see that the initial value of the signal is the specified 0 value,+followed by 8's. You might be surprised to see /two/ zeros instead of just a+single zero. What happens is that in Clash you get to see the output of the+circuit /before/ the clock becomes actives. In other words, in Clash you get to+describe the powerup values of registers too. Whether this is a defined or+unknown value depends on your hardware target, and can be configured by using a+different synthesis @'Domain'@. The default synthesis domain, @'System', assumes+that registers do have a powerup value - as is true for most FPGA platforms in+most contexts.+-}++{- $mac2+The 'register' function is our primary sequential building block to capture+/state/. It is used internally by one of the "Clash.Prelude" function that we+will use to describe our MAC circuit. Note that the following paragraphs will+only show one of many ways to specify a sequential circuit, at the section we+will show a couple more.++A principled way to describe a sequential circuit is to use one of the classic+machine models, within the Clash prelude library offer standard function to+support the <http://en.wikipedia.org/wiki/Mealy_machine Mealy machine>.+To improve sharing, we will combine the transition function and output function+into one. This gives rise to the following Mealy specification of the MAC+circuit:++@+macT acc (x, y) = (acc', o)+  where+    acc' = ma acc (x, y)+    o    = acc+@++Note that the @where@ clause and explicit tuple are just for demonstrative+purposes, without loss of sharing we could've also written:++@+macT acc inp = (ma acc inp, acc)+@++Going back to the original specification we note the following:++  * 'acc' is the current /state/ of the circuit.+  * '(x, y)' is its input.+  * 'acc'' is the updated, or next, /state/.+  * 'o' is the output.++When we examine the type of 'macT' we see that is still completely combinational:++>>> :t macT+macT :: Num a => a -> (a, a) -> (a, a)++The "Clash.Prelude" library contains a function that creates a sequential+circuit from a combinational circuit that has the same Mealy machine type /+shape of @macT@:++@+mealy+  :: ('HiddenClockResetEnable' dom dom, 'Clash.XException.NFDataX' s)+  => (s -> i -> (s,o))+  -> s+  -> ('Signal' dom i -> 'Signal' dom o)+mealy f initS = ...+@++The complete sequential MAC circuit can now be specified as:++@+mac = 'mealy' macT 0+@++Where the first argument of @'mealy'@ is our @macT@ function, and the second+argument is the initial state, in this case 0. We can see it is functioning+correctly in our interpreter:++>>> import qualified Data.List as L+>>> L.take 4 $ simulate @System mac [(1,1),(2,2),(3,3),(4,4)]+[0,1,5,14]++Where we simulate our sequential circuit over a list of input samples and take+the first 4 output samples. We have now completed our first sequential circuit+and have made an initial confirmation that it is working as expected.+-}++{- $mac3+We are now almost at the point that we can create actual hardware, in the form+of a <http://en.wikipedia.org/wiki/VHDL VHDL> netlist, from our sequential+circuit specification. The first thing we have to do is create a function+called 'topEntity' and ensure that it has a __monomorphic__ type. In our case+that means that we have to give it an explicit type annotation. It might not+always be needed, you can always check the type with the @:t@ command and see+if the function is monomorphic:++@+topEntity+  :: 'Clock' 'System'+  -> 'Reset' 'System'+  -> 'Signal' 'System' ('Signed' 9, 'Signed' 9)+  -> 'Signal' 'System' ('Signed' 9)+topEntity = 'exposeClockResetEnable' mac+@++Which makes our circuit work on 9-bit signed integers. Including the above+definition, our complete @MAC.hs@ should now have the following content:++@+module MAC where++import "Clash.Prelude"++ma acc (x,y) = acc + x * y++macT acc (x,y) = (acc',o)+  where+    acc' = ma acc (x,y)+    o    = acc++mac = 'mealy' macT 0++topEntity+  :: 'Clock' 'System'+  -> 'Reset' 'System'+  -> 'Enable' 'System'+  -> 'Signal' 'System' ('Signed' 9, 'Signed' 9)+  -> 'Signal' 'System' ('Signed' 9)+topEntity = 'exposeClockResetEnable' mac+@++The 'topEntity' function is the starting point for the Clash compiler to+transform your circuit description into a VHDL netlist. It must meet the+following restrictions in order for the Clash compiler to work:++  * It must be completely monomorphic+  * It must be completely first-order+  * Although not strictly necessary, it is recommended to /expose/ 'Hidden'+    clock and reset arguments, as it makes user-controlled+    <Clash-Tutorial.html#annotations name assignment> in the generated HDL+    easier to do.++Our 'topEntity' meets those restrictions, and so we can convert it successfully+to VHDL by executing the @:vhdl@ command in the interpreter. This will create+a directory called 'vhdl', which contains a directory called @MAC@, which+ultimately contains all the generated VHDL files. You can now load these files+into your favourite VHDL synthesis tool, marking @mac_topentity.vhdl@ as the file+containing the top level entity.+-}++{- $mac4+There are multiple reasons as to why you might want to create a so-called+/test bench/ for the generated HDL:++  * You want to compare post-synthesis / post-place&route behavior to that of+    the behavior of the original generated HDL.+  * Need representative stimuli for your dynamic power calculations.+  * Verify that the HDL output of the Clash compiler has the same behavior as+    the Haskell / Clash specification.++For these purposes, you can have the Clash compiler generate a /test bench/. In+order for the Clash compiler to do this you need to do one of the following:++  * Create a function called /testBench/ in the root module.+  * Annotate your /topEntity/ function (or function with a+    <Clash-Tutorial.html#g:12 Synthesize> annotation)+    with a 'TestBench' annotation.++For example, you can test the earlier defined /topEntity/ by:++@+import "Clash.Explicit.Testbench"++topEntity+  :: 'Clock' System+  -> 'Reset' System+  -> 'Enable' System+  -> 'Signal' System ('Signed' 9, 'Signed' 9)+  -> 'Signal' System ('Signed' 9)+topEntity = 'exposeClockReset' mac++testBench :: 'Signal' System Bool+testBench = done+  where+    testInput    = 'stimuliGenerator' clk rst $('listToVecTH' [(1,1) :: ('Signed' 9,'Signed' 9),(2,2),(3,3),(4,4)])+    expectOutput = 'outputVerifier'' clk rst $('listToVecTH' [0 :: 'Signed' 9,1,5,14,14,14,14])+    done         = expectOutput (topEntity clk rst en testInput)+    en           = 'enableGen'+    clk          = 'tbSystemClockGen' (not '<$>' done)+    rst          = 'systemResetGen'+@++This will create a stimulus generator that creates the same inputs as we used+earlier for the simulation of the circuit, and creates an output verifier that+compares against the results we got from our earlier simulation. We can even+simulate the behavior of the /testBench/:++>>> sampleN 8 testBench+[False,False,False,False,False+cycle(<Clock: System>): 5, outputVerifier+expected value: 14, not equal to actual value: 30+,False+cycle(<Clock: System>): 6, outputVerifier+expected value: 14, not equal to actual value: 46+,False+cycle(<Clock: System>): 7, outputVerifier+expected value: 14, not equal to actual value: 62+,False]++We can see that for the first 4 samples, everything is working as expected,+after which warnings are being reported. The reason is that 'stimuliGenerator'+will keep on producing the last sample, (4,4), while the 'outputVerifier'' will+keep on expecting the last sample, 14. In the VHDL testbench these errors won't+show, as the global clock will be stopped after 4 ticks.++You should now again run @:vhdl@ in the interpreter; this time the compiler+will take a bit longer to generate all the circuits. Inside the @.\/vhdl\/MAC@+directory you will now also find a /mac_testbench/ subdirectory containing all+the @vhdl@ files for the /test bench/.+++After compilation is finished you  load all the files in your favourite VHDL+simulation tool. Once all files are loaded into the VHDL simulator, run the+simulation on the @mac_testbench_testbench@ entity.+On questasim / modelsim: doing a @run -all@ will finish once the output verifier+will assert its output to @true@. The generated testbench, modulo the clock+signal generator(s), is completely synthesizable. This means that if you want to+test your circuit on an FPGA, you will only have to replace the clock signal+generator(s) by actual clock sources, such as an onboard PLL.+-}++{- $mac5+Aside from being able to generate VHDL, the Clash compiler can also generate Verilog+and SystemVerilog. You can repeat the previous two parts of the tutorial, but+instead of executing the @:vhdl@ command, you execute the @:verilog@ or+@:sytemverilog@ command in the interpreter. This will create a directory called+@verilog@, respectively @systemverilog@, which contains a directory called @MAC@,+which ultimately contains all the generated Verilog and SystemVerilog files.+Verilog files end in the file extension @v@, while SystemVerilog files end in+the file extension @sv@.++This concludes the main part of this section on \"Your first circuit\", read on+for alternative specifications for the same 'mac' circuit, or just skip to the+next section where we will describe another DSP classic: an FIR filter+structure.+-}++{- $mac6+* __'Num' instance for 'Signal'__:++    @'Signal' a@ is also also considered a 'Num'eric type as long as the value+    type /a/ is also 'Num'eric.  This means that we can also use the standard+    numeric operators, such as ('*') and ('+'), directly on signals. An+    alternative specification of the 'mac' circuit will also use the 'register'+    function directly:++    @+    macN (x,y) = acc+      where+        acc = 'register' 0 (acc + x * y)+    @++* __'Applicative' instance for 'Signal'__:++    We can also mix the combinational 'ma' function, with the sequential+    'register' function, by lifting the 'ma' function to the sequential 'Signal'+    domain using the operators ('<$>' and '<*>') of the 'Applicative' type+    class:++    @+    macA (x,y) = acc+      where+        acc  = 'register' 0 acc'+        acc' = ma '<$>' acc '<*>' 'bundle' (x,y)+    @++* __'Control.Monad.State.Lazy.State' Monad__++    We can also implement the original @macT@ function as a+    @'Control.Monad.State.Lazy.State'@+    monadic computation. First we must add an extra import statement, right+    after the import of "Clash.Prelude":++    @+    import Control.Monad.State+    @++    We can then implement macT as follows:++    @+    macTS (x,y) = do+      acc <- 'Control.Monad.State.Lazy.get'+      'Control.Monad.State.Lazy.put' (acc + x * y)+      return acc+    @++    We can use the 'mealy' function again, although we will have to change+    position of the arguments and result:++    @+    asStateM+      :: ( 'HiddenClockResetEnable' dom dom+         , 'NFDataX' s )+      => (i -> 'Control.Monad.State.Lazy.State' s o)+      -> s+      -> ('Signal' dom i -> 'Signal' dom o)+    asStateM f i = 'mealy' g i+      where+        g s x = let (o,s') = 'Control.Monad.State.Lazy.runState' (f x) s+                in  (s',o)+    @++    We can then create the complete 'mac' circuit as:++    @+    macS = asStateM macTS 0+    @+-}++{- $higher_order+An FIR filter is defined as: the dot-product of a set of filter coefficients and+a window over the input, where the size of the window matches the number+of coefficients.++@+dotp as bs = 'sum' ('zipWith' (*) as bs)++fir coeffs x_t = y_t+  where+    y_t = dotp coeffs xs+    xs  = 'window' x_t++topEntity+  :: 'Clock' 'System'+  -> 'Reset' 'System'+  -> 'Enable' 'System'+  -> 'Signal' 'System' ('Signed' 16)+  -> 'Signal' 'System' ('Signed' 16)+topEntity = exposeClockResetEnableEnable (fir (0 ':>' 1 ':>' 2 ':>' 3 ':>' 'Nil'))+@++Here we can see that, although the Clash compiler handles recursive function+definitions poorly, many of the regular patterns that we often encounter in+circuit design are already captured by the higher-order functions that are+present for the 'Vec'tor type.+-}++{- $composition_sequential+Given a function @f@ of type:++@+__f__ :: Int -> (Bool, Int) -> (Int, (Int, Bool))+@++When we want to make compositions of @f@ in @g@ using 'mealy', we have to+write:++@+g a b c = (b1,b2,i2)+  where+    (i1,b1) = 'unbundle' ('mealy' f 0 ('bundle' (a,b)))+    (i2,b2) = 'unbundle' ('mealy' f 3 ('bundle' (c,i1)))+@++Why do we need these 'bundle', and 'unbundle' functions you might ask? When we+look at the type of 'mealy':++@+__mealy__ :: (s -> i -> (s,o))+      -> s+      -> ('Signal' i -> 'Signal' o)+@++we see that the resulting function has an input of type @'Signal' i@, and an+output of @'Signal' o@. However, the type of @(a,b)@ in the definition of @g@ is:+@('Signal' Bool, 'Signal' Int)@. And the type of @(i1,b1)@ is of type+@('Signal' Int, 'Signal' Bool)@.++Syntactically, @'Signal' dom (Bool,Int)@ and @('Signal' dom Bool,+'Signal' dom Int)@ are /unequal/.+So we need to make a conversion between the two, that is what 'bundle' and+'unbundle' are for. In the above case 'bundle' gets the type:++@+__bundle__ :: ('Signal' dom Bool, 'Signal' dom Int) -> 'Signal' dom (Bool,Int)+@++and 'unbundle':++@+__unbundle__ :: 'Signal' dom (Int,Bool) -> ('Signal' dom Int, 'Signal' dom Bool)+@++The /true/ types of these two functions are, however:++@+__bundle__   :: 'Bundle' a => 'Unbundled' domain a -> 'Signal' dom a+__unbundle__ :: 'Bundle' a => 'Signal' dom a -> 'Unbundled' domain a+@++'Unbundled' is an <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#associated-data-and-type-families associated type family>+belonging to the 'Bundle' <http://en.wikipedia.org/wiki/Type_class type class>,+which, together with 'bundle' and 'unbundle' defines the isomorphism between a+product type of 'Signal's and a 'Signal' of a product type. That is, while+@(Signal a, Signal b)@ and @Signal (a,b)@ are not equal, they are /isomorphic/+and can be converted from, or to, the other using 'bundle' and 'unbundle'.++Instances of this 'Bundle' type-class are defined as /isomorphisms/ for:++  * All tuples up to and including 62-tuples (GHC limit)+  * The 'Vec'tor type++But they are defined as /identities/ for:++  * All elementary / primitive types such as: 'Bit', 'Bool', @'Signed' n@, etc.++That is:++@+instance 'Bundle' (a,b) where+  type 'Unbundled' domain (a,b) = ('Signal' dom a, 'Signal' dom b)+  bundle   (a,b) = (,) '<$>' a '<*>' b+  unbundle tup   = (fst '<$>' tup, snd '<*>' tup)+@++but,++@+instance 'Bundle' Bool where+  type 'Unbundled' clk Bool = 'Signal' clk Bool+  bundle   s = s+  unbundle s = s+@++What you need take away from the above is that a product type (e.g. a tuple) of+'Signal's is not syntactically equal to a 'Signal' of a product type, but that+the functions of the 'Bundle' type class allow easy conversion between the two.++As a final note on this section we also want to mention the 'mealyB' function,+which does the bundling and unbundling for us:++@+mealyB+  :: ('Bundle' i, 'Bundle' o)+  => (s -> i -> (s,o))+  -> s+  -> 'Unbundled' domain i+  -> 'Unbundled' domain o+@++Using 'mealyB' we can define @g@ as:++@+g a b c = (b1,b2,i2)+  where+    (i1,b1) = 'mealyB' f 0 (a,b)+    (i2,b2) = 'mealyB' f 3 (c,i1)+@++The general rule of thumb is: always use 'mealy', unless you do pattern matching+or construction of product types, then use 'mealyB'.+-}++{- $annotations #annotations#+'Synthesize' annotations allow us to control hierarchy and naming aspects of the+Clash compiler, specifically, they allow us to:++    * Assign names to entities (VHDL) \/ modules ((System)Verilog), and their+      ports.+    * Put generated HDL files of a logical (sub)entity in their own directory.+    * Use cached versions of generated HDL, i.e., prevent recompilation of+      (sub)entities that have not changed since the last run. Caching is based+      on a @.manifest@ which is generated alongside the HDL; deleting this file+      means deleting the cache; changing this file will result in /undefined/+      behavior.++Functions with a 'Synthesize' annotation must adhere to the following+restrictions:++    * Although functions with a 'Synthesize' annotation can of course depend+      on functions with another 'Synthesize' annotation, they must not be+      mutually recursive.+    * Functions with a 'Synthesize' annotation must be completely /monomorphic/+      and /first-order/, and cannot have any /non-representable/ arguments or+      result.++Also take the following into account when using 'Synthesize' annotations.++    * The Clash compiler is based on the GHC Haskell compiler, and the GHC+      machinery does not understand 'Synthesize' annotations and it might+      subsequently decide to inline those functions. You should therefor also+      add a @{\-\# NOINLINE f \#-\}@ pragma to the functions which you give+      a 'Synthesize' functions.+    * Functions with a 'Synthesize' annotation will not be specialized+      on constants.++Finally, the root module, the module which you pass as an argument to the+Clash compiler must either have:++    * A function with a 'Synthesize' annotation.+    * A function called /topEntity/.++You apply 'Synthesize' annotations to functions using an @ANN@ pragma:++@+{\-\# ANN topEntity (Synthesize {t_name = ..., ...  }) \#-\}+topEntity x = ...+@++For example, given the following specification:++@+module Blinker where++import "Clash.Signal"+import "Clash.Prelude"+import "Clash.Intel.ClockGen"++'createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}+'createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}++topEntity+  :: Clock \"DomInput\"+  -> Signal \"DomInput\" Bool+  -> Signal \"Dom50\" Bit+  -> Signal \"Dom50\" (BitVector 8)+topEntity clk rst =+    'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . Clash.Prelude.isRising 1) pllOut rstSync 'enableGen'+  where+    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' @"Dom50" (SSymbol @"altpll50") clk ('Clash.Signal.unsafeFromLowPolarity' rst)+    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeFromLowPolarity' pllStable) enableGen++blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)+  where+    -- clock frequency = 50e6  (50 MHz)+    -- led update rate = 333e-3 (every 333ms)+    cnt_max = 16650000 :: ('Index' 16650001) -- 50e6 * 333e-3++    cntr' | cntr == cnt_max = 0+          | otherwise       = cntr + 1++    mode' | key1R     = not mode+          | otherwise = mode++    leds' | cntr == 0 = if mode then complement leds+                                else rotateL leds 1+          | otherwise = leds+@++The Clash compiler will normally generate the following @blinker_topEntity.vhdl@ file:++@+-- Automatically generated VHDL-93+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use std.textio.all;+use work.all;+use work.blinker_types.all;++entity blinker_topentity is+  port(-- clock+       clk  : in blinker_types.clk_dominput;+       rst  : in boolean;+       x    : in std_logic;+       leds : out std_logic_vector(7 downto 0));+end;++architecture structural of blinker_topentity is+ ...+end;+@++However, if we add the following 'Synthesize' annotation in the file:++@+{\-\# ANN topEntity+  ('Synthesize'+    { t_name   = "blinker"+    , t_inputs = [PortName \"CLOCK_50\", PortName \"KEY0\", PortName \"KEY1\"]+    , t_output = PortName \"LED\"+    }) \#-\}+@++The Clash compiler will generate the following @blinker.vhdl@ file instead:++@+-- Automatically generated VHDL-93+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use std.textio.all;+use work.all;+use work.blinker_types.all;++entity blinker is+  port(-- clock+       CLOCK_50 : in blinker_types.clk_dominput;+       KEY0     : in boolean;+       KEY1     : in std_logic;+       LED      : out std_logic_vector(7 downto 0));+end;++architecture structural of blinker is+ ...+end;+@++Where we now have:++* A top-level component that is called @blinker@.+* Inputs and outputs that have a /user/-chosen name: @CLOCK_50@, @KEY0@, @KEY1@, @LED@, etc.++See the documentation of 'Synthesize' for the meaning of all its fields.+-}++{- $primitives #primitives#+There are times when you already have an existing piece of IP, or there are+times where you need the VHDL to have a specific shape so that the VHDL+synthesis tool can infer a specific component. In these specific cases you can+resort to defining your own VHDL primitives. Actually, most of the primitives+in Clash are specified in the same way as you will read about in this section.+There are perhaps 10 (at most) functions which are truly hard-coded into the+Clash compiler. You can take a look at the files in+<https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/vhdl>+(or <https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/verilog>+for the Verilog primitives or <https://github.com/clash-lang/clash-compiler/tree/master/clash-lib/prims/systemverilog>+for the SystemVerilog primitives) if you want to know which functions are defined+as \"regular\" primitives. The compiler looks for primitives in four locations:++* The official install location: e.g.++    * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/common@+    * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/commonverilog@+    * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/systemverilog@+    * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/verilog@+    * @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-lib\-<VERSION\>\/prims\/vhdl@++* Directories indicated by a 'Clash.Annotations.Primitive.Primitive' annotation+* The current directory (the location given by @pwd@)+* The include directories specified on the command-line: @-i\<DIR\>@++Where redefined primitives in the current directory or include directories will+overwrite those in the official install location. For now, files containing+primitive definitions must have an @.json@ file-extension.++Clash differentiates between two types of primitives, /expression/ primitives+and /declaration/ primitives, corresponding to whether the primitive is a VHDL+/expression/ or a VHDL /declaration/. We will first explore /expression/+primitives, using 'Signed' multiplication ('*') as an example. The+"Clash.Sized.Internal.Signed" module specifies multiplication as follows:++@+(*#) :: 'GHC.TypeLits.KnownNat' n => 'Signed' n -> 'Signed' n -> 'Signed' n+(S a) *# (S b) = fromInteger_INLINE (a * b)+{\-\# NOINLINE (*#) \#-\}+@++For which the VHDL /expression/ primitive is:++@+{ \"BlackBox\" :+  { "name"     : "Clash.Sized.Internal.Signed.*#"+  , "kind"     : \"Expression\"+  , "template" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"+  }+}+@++The @name@ of the primitive is the /fully qualified/ name of the function you+are creating the primitive for. Because we are creating an /expression/+primitive the kind must be set to @Expression@. As the name suggest, it is a VHDL+/template/, meaning that the compiler must fill in the holes heralded by the+tilde (~). Here:++  * @~ARG[1]@ denotes the second argument given to the @(*#)@ function, which+    corresponds to the LHS of the ('*') operator.+  * @~ARG[2]@ denotes the third argument given to the @(*#)@ function, which+    corresponds to the RHS of the ('*') operator.+  * @~LIT[0]@ denotes the first argument given to the @(*#)@ function, with+    the extra condition that it must be a @LIT@eral. If for some reason this+    first argument does not turn out to be a literal then the compiler will+    raise an error. This first arguments corresponds to the \"@'KnownNat' n@\"+    class constraint.++An extensive list with all of the template holes will be given the end of this+section. What we immediately notice is that class constraints are counted as+normal arguments in the primitive definition. This is because these class+constraints are actually represented by ordinary record types, with fields+corresponding to the methods of the type class. In the above case, 'KnownNat'+is actually just like a @newtype@ wrapper for 'Integer'.++The second kind of primitive that we will explore is the /declaration/ primitive.+We will use 'blockRam#' as an example, for which the Haskell/Clash code is:++@+{\-\# LANGUAGE BangPatterns \#\-\}++module BlockRam where++import Clash.Explicit.Prelude+import qualified Data.Vector           as V+import           GHC.Stack             (HasCallStack, withFrozenCallStack)++import Clash.Signal.Internal+  (Clock, Signal (..), (.&&.))+import Clash.Sized.Vector     (Vec, toList)+import Clash.XException       (defaultSeqX)+++blockRam#+  :: ( HasCallStack+     , NFDataX a )+  => 'Clock' dom           -- ^ 'Clock' to synchronize to+  -> 'Enable' dom          -- ^ Global enable+  -> 'Vec' n a             -- ^ Initial content of the BRAM, also+                           -- determines the size, @n@, of the BRAM.+                           --+                           -- __NB__: __MUST__ be a constant.+  -> 'Signal' dom Int      -- ^ Read address @r@+  -> 'Signal' dom Bool     -- ^ Write enable+  -> 'Signal' dom Int      -- ^ Write address @w@+  -> 'Signal' dom a        -- ^ Value to write (at address @w@)+  -> 'Signal' dom a        -- ^ Value of the @blockRAM@ at address @r@ from+                           -- the previous clock cycle+blockRam# (Clock _) gen content rd wen =+  go+    (V.fromList ('toList' content))+    (withFrozenCallStack ('deepErrorX' "blockRam: intial value undefined"))+    (fromEnable gen)+    rd+    (fromEnable gen '.&&.' wen)+ where+  go !ram o ret\@(~(re :- res)) rt\@(~(r :- rs)) et\@(~(e :- en)) wt\@(~(w :- wr)) dt\@(~(d :- din)) =+    let ram' = d ``defaultSeqX`` upd ram e (fromEnum w) d+        o'   = if re then ram V.! r else o+    in  o ``seqX`` o :- (ret ``seq`` rt ``seq`` et ``seq`` wt ``seq`` dt ``seq`` go ram' o' res rs en wr din)++  upd ram we waddr d = case maybeIsX we of+    Nothing -> case maybeIsX waddr of+      Nothing -> V.map (const (seq waddr d)) ram+      Just wa -> ram V.// [(wa,d)]+    Just True -> case maybeIsX waddr of+      Nothing -> V.map (const (seq waddr d)) ram+      Just wa -> ram V.// [(wa,d)]+    _ -> ram+{\-\# NOINLINE blockRam# \#\-\}+@++And for which the /declaration/ primitive is:++@+{ \"BlackBox\" :+  { "name" : "Clash.Explicit.BlockRam.blockRam#"+  , "kind" : \"Declaration\"+  , "type" :+"blockRam#+  :: ( HasCallStack  --       ARG[0]+     , NFDataX a ) --       ARG[1]+  => Clock dom       -- clk,  ARG[2]+  -> Enable dom      -- en,   ARG[3]+  -> Vec n a         -- init, ARG[4]+  -> Signal dom Int  -- rd,   ARG[5]+  -> Signal dom Bool -- wren, ARG[6]+  -> Signal dom Int  -- wr,   ARG[7]+  -> Signal dom a    -- din,  ARG[8]+  -> Signal dom a"+    , "template" :+"-- blockRam begin+~GENSYM[~RESULT_blockRam][0] : block+  signal ~GENSYM[~RESULT_RAM][1] : ~TYP[4] := ~CONST[4];+  signal ~GENSYM[rd][3]  : integer range 0 to ~LENGTH[~TYP[4]] - 1;+  signal ~GENSYM[wr][4]  : integer range 0 to ~LENGTH[~TYP[4]] - 1;+begin+  ~SYM[3] <= to_integer(~ARG[5])+  -- pragma translate_off+                mod ~LENGTH[~TYP[4]]+  -- pragma translate_on+                ;++  ~SYM[4] <= to_integer(~ARG[7])+  -- pragma translate_off+                mod ~LENGTH[~TYP[4]]+  -- pragma translate_on+                ;+~IF ~VIVADO ~THEN+  ~SYM[5] : process(~ARG[2])+  begin+    if rising_edge(~ARG[2]) then+      if ~ARG[6] ~IF ~ISACTIVEENABLE[3] ~THEN and ~ARG[3] ~ELSE ~FI then+        ~SYM[1](~SYM[4]) <= ~TOBV[~ARG[8]][~TYP[8]];+      end if;+      ~RESULT <= fromSLV(~SYM[1](~SYM[3]))+      -- pragma translate_off+      after 1 ps+      -- pragma translate_on+      ;+    end if;+  end process; ~ELSE+  ~SYM[5] : process(~ARG[2])+  begin+    if rising_edge(~ARG[2]) then+      if ~ARG[6] ~IF ~ISACTIVEENABLE[3] ~THEN and ~ARG[3] ~ELSE ~FI then+        ~SYM[1](~SYM[4]) <= ~ARG[8];+      end if;+      ~RESULT <= ~SYM[1](~SYM[3])+      -- pragma translate_off+      after 1 ps+      -- pragma translate_on+      ;+    end if;+  end process; ~FI+end block;+--end blockRam"+  }+}+@++Again, the @name@ of the primitive is the fully qualified name of the function+you are creating the primitive for. Because we are creating a /declaration/+primitive the /kind/ must be set to @Declaration@. Instead of discussing what the+individual template holes mean in the above context, we will instead just give+a general listing of the available template holes:++* @~RESULT@: Signal to which the result of a primitive must be assigned+  to. NB: Only used in a /declaration/ primitive.+* @~ARG[N]@: @(N+1)@'th argument to the function.+* @~LIT[N]@: @(N+1)@'th argument to the function. An extra condition that must+  hold is that this @(N+1)@'th argument is an (integer) literal.+* @~CONST[N]@: @(N+1)@'th argument to the function. Clash will try to reduce+* this to a literal, even if it would otherwise consider it too expensive. As+* opposed to ~LIT, ~CONST will render a valid HDL expression.+* @~TYP[N]@: VHDL type of the @(N+1)@'th argument.+* @~TYPO@: VHDL type of the result.+* @~TYPM[N]@: VHDL type/name/ of the @(N+1)@'th argument; used in /type/+  /qualification/.+* @~TYPM@: VHDL type/name/ of the result; used in /type qualification/.+* @~ERROR[N]@: Error value for the VHDL type of the @(N+1)@'th argument.+* @~ERRORO@: Error value for the VHDL type of the result.+* @~GENSYM[\<NAME\>][N]@: Create a unique name, trying to stay as close to+  the given @\<NAME\>@ as possible. This unique symbol can be referred to in+  other places using @~SYM[N]@.+* @~SYM[N]@: a reference to the unique symbol created by @~GENSYM[\<NAME\>][N]@.+* @~SIGD[\<HOLE\>][N]@: Create a signal declaration, using @\<HOLE\>@ as the name+  of the signal, and the type of the @(N+1)@'th argument.+* @~SIGDO[\<HOLE\>]@: Create a signal declaration, using @\<HOLE\>@ as the name+  of the signal, and the type of the result.+* @~TYPELEM[\<HOLE\>]@: The element type of the vector type represented by @\<HOLE\>@.+  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.+* @~COMPNAME@: The name of the component in which the primitive is instantiated.+* @~LENGTH[\<HOLE\>]@: The vector length of the type represented by @\<HOLE\>@.+* @~DEPTH[\<HOLE\>]@: The tree depth of the type represented by @\<HOLE\>@.+  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.+* @~SIZE[\<HOLE\>]@: The number of bits needed to encode the type represented by @\<HOLE\>@.+  The content of @\<HOLE\>@ must either be: @TYP[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.+* @~IF \<CONDITION\> ~THEN \<THEN\> ~ELSE \<ELSE\> ~FI@: renders the \<ELSE\>+  part when \<CONDITION\> evaluates to /0/, and renders the \<THEN\> in all+  other cases. Valid @\<CONDITION\>@s are @~LENGTH[\<HOLE\>]@, @~SIZE[\<HOLE\>]@,+  @~DEPTH[\<HOLE\>]@, @~VIVADO@, @~IW64@, @~ISLIT[N]@, @~ISVAR[N], @~ISACTIVEENABLE[N]@,+  @~ISSYNC[N]@, and @~AND[\<HOLE1\>,\<HOLE2\>,..]@.+* @~VIVADO@: /1/ when Clash compiler is invoked with the @-fclash-xilinx@ or+  @-fclash-vivado@ flag. To be used with in an @~IF .. ~THEN .. ~ElSE .. ~FI@+  statement.+* @~TOBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the+  expression in @\<HOLE\>@ is converted to a bit vector (@std_logic_vector@).+  The @\<TYPE\>@ hole indicates the type of the expression and must be either+  @~TYP[N]@, @~TYPO@, or @~TYPELEM[\<HOLE\>]@.+* @~FROMBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the+  expression in @\<HOLE\>@, which has a bit vector (@std_logic_vector@) type, is+  converted to type indicated by @\<TYPE\>@. The @\<TYPE\>@ hole indicates the+  must be either @~TYP[N]@, @~TYPO@, or @~TYPELEM[\<HOLE\>]@.+* @~INCLUDENAME[N]@: the generated name of the @N@'th included component.+* @~FILEPATH[\<HOLE\>]@: The argument mentioned in @\<HOLE\>@ is a file which+  must be copied to the location of the generated HDL.+* @~GENERATE@: Verilog: create a /generate/ statement, except when already in+  as /generate/ context.+* @~ENDGENERATE@: Verilog: create an /endgenerate/ statement, except when already+  in a /generate/ context.+* @~ISLIT[N]@: Is the @(N+1)@'th argument to the function a literal.+* @~ISVAR[N]@: Is the @(N+1)@'th argument to the function explicitly not a+  literal+* @~TAG[N]@: Name of given domain. Errors when called on an argument which is not+  a 'KnownDomain', 'Reset', or 'Clock'.+* @~PERIOD[N]@: Clock period of given domain. Errors when called on an argument+  which is not a 'KnownDomain' or 'KnownConf'.+* @~ISACTIVEENABLE[N]@: Is the @(N+1)@'th argument a an Enable line NOT set to a+  constant True. Can be used instead of deprecated (and removed) template tag+  ~ISGATED. Errors when called on an argument which is not a signal of bools.+* @~ISSYNC[N]@: Does synthesis domain at the @(N+1)@'th argument have synchronous resets. Errors+  when called on an argument which is not a 'KnownDomain' or 'KnownConf'.+* @~ISINITDEFINED[N]@: Does synthesis domain at the @(N+1)@'th argument have defined initial+  values. Errors when called on an argument which is not a 'KnownDomain' or 'KnownConf'.+* @~ACTIVEEDGE[edge][N]@: Does synthesis domain at the @(N+1)@'th argument respond to+  /edge/. /edge/ must be one of 'Falling' or 'Rising'. Errors when called on an+  argument which is not a 'KnownDomain' or 'KnownConf'.+* @~AND[\<HOLE1\>,\<HOLE2\>,..]@: Logically /and/ the conditions in the @\<HOLE\>@'s+* @~VARS[N]@: VHDL: Return the variables at the @(N+1)@'th argument argument.+* @~NAME[N]@: Render the @(N+1)@'th string literal argument as an identifier+  instead of a string literal. Fails when the @(N+1)@'th argument is not a+  string literal.+* @~DEVNULL[\<HOLE\>]@: Render all dependencies of @\<HOLE\>@, but disregard direct output+* @~REPEAT[\<HOLE\>][N]@: Repeat literal value of @\<HOLE\>@ a total of @N@ times.+* @~TEMPLATE[\<HOLE1\>][\<HOLE2\>]@: Render a file @\<HOLE1\>@ with contents @\<HOLE2\>@.+++Some final remarks to end this section: VHDL primitives are there to instruct the+Clash compiler to use the given VHDL template, instead of trying to do normal+synthesis. As a consequence you can use constructs inside the Haskell+definitions that are normally not synthesizable by the Clash compiler. However,+VHDL primitives do not give us /co-simulation/: where you would be able to+simulate VHDL and Haskell in a /single/ environment. If you still want to+simulate your design in Haskell, you will have to describe, in a cycle- and+bit-accurate way, the behavior of that (potentially complex) IP you are trying+to include in your design.++Perhaps in the future, someone will figure out how to connect the two simulation+worlds, using e.g. VHDL's foreign function interface VHPI.+-}++{- $vprimitives+For those who are interested, the equivalent Verilog primitives are:++@+{ \"BlackBox\" :+  { "name"     : "Clash.Sized.Internal.Signed.*#"+  , "kind"     : \"Expression\"+  , "template" : "~ARG[1] * ~ARG[2]"+  }+}+@++and++@+{ \"BlackBox\" :+  { "name" : "Clash.Explicit.BlockRam.blockRam#"+  , "kind" : \"Declaration\"+  , "type" :+"blockRam#+  :: ( HasCallStack  --       ARG[0]+     , NFDataX a ) --       ARG[1]+  => Clock dom       -- clk,  ARG[2]+  => Enable dom      -- en,   ARG[3]+  -> Vec n a         -- init, ARG[4]+  -> Signal dom Int  -- rd,   ARG[5]+  -> Signal dom Bool -- wren, ARG[6]+  -> Signal dom Int  -- wr,   ARG[7]+  -> Signal dom a    -- din,  ARG[8]+  -> Signal dom a"+    , "outputReg" : true+    , "template" :+"// blockRam begin+reg ~TYPO ~GENSYM[~RESULT_RAM][0] [0:~LENGTH[~TYP[4]]-1];++reg ~TYP[4] ~GENSYM[ram_init][2];+integer ~GENSYM[i][3];+initial begin+  ~SYM[2] = ~CONST[4];+  for (~SYM[3]=0; ~SYM[3] < ~LENGTH[~TYP[4]]; ~SYM[3] = ~SYM[3] + 1) begin+    ~SYM[0][~LENGTH[~TYP[4]]-1-~SYM[3]] = ~SYM[2][~SYM[3]*~SIZE[~TYPO]+:~SIZE[~TYPO]];+  end+end+~IF ~ISACTIVEENABLE[3] ~THEN+always @(posedge ~ARG[2]) begin : ~GENSYM[~RESULT_blockRam][4]~IF ~VIVADO ~THEN+  if (~ARG[3]) begin+    if (~ARG[6]) begin+      ~SYM[0][~ARG[7]] <= ~ARG[8];+    end+    ~RESULT <= ~SYM[0][~ARG[5]];+  end~ELSE+  if (~ARG[6] & ~ARG[3]) begin+    ~SYM[0][~ARG[7]] <= ~ARG[8];+  end+  if (~ARG[3]) begin+    ~RESULT <= ~SYM[0][~ARG[5]];+  end~FI+end~ELSE+always @(posedge ~ARG[2]) begin : ~SYM[4]+  if (~ARG[6]) begin+    ~SYM[0][~ARG[7]] <= ~ARG[8];+  end+  ~RESULT <= ~SYM[0][~ARG[5]];+end~FI+// blockRam end"+  }+}+@++-}++{- $svprimitives+And the equivalent SystemVerilog primitives are:++@+{ \"BlackBox\" :+  { "name"     : "Clash.Sized.Internal.Signed.*#"+  , "kind"     : \"Expression\"+  , "template" : "~ARG[1] * ~ARG[2]"+  }+}+@++and++@+{ \"BlackBox\" :+  { "name" : "Clash.Explicit.BlockRam.blockRam#"+  , "kind" : \"Declaration\"+  , "type" :+"blockRam#+  :: ( HasCallStack  --       ARG[0]+     , NFDataX a ) --       ARG[1]+  => Clock dom       -- clk,  ARG[2]+  -> Enable dom      -- en,   ARG[3]+  -> Vec n a         -- init, ARG[4]+  -> Signal dom Int  -- rd,   ARG[5]+  -> Signal dom Bool -- wren, ARG[6]+  -> Signal dom Int  -- wr,   ARG[7]+  -> Signal dom a    -- din,  ARG[8]+  -> Signal dom a"+    , "template" :+"// blockRam begin+~SIGD[~GENSYM[RAM][0]][4];+logic [~SIZE[~TYP[8]]-1:0] ~GENSYM[~RESULT_q][1];+initial begin+  ~SYM[0] = ~CONST[4];+end~IF ~ISACTIVEENABLE[3] ~THEN+always @(posedge ~ARG[2]) begin : ~GENSYM[~COMPNAME_blockRam][2]~IF ~VIVADO ~THEN+  if (~ARG[3]) begin+    if (~ARG[6]) begin+      ~SYM[0][~ARG[7]] <= ~TOBV[~ARG[8]][~TYP[8]];+    end+    ~SYM[1] <= ~SYM[0][~ARG[5]];+  end~ELSE+  if (~ARG[6] & ~ARG[3]) begin+    ~SYM[0][~ARG[7]] <= ~TOBV[~ARG[8]][~TYP[8]];+  end+  if (~ARG[3]) begin+    ~SYM[1] <= ~SYM[0][~ARG[5]];+  end~FI+end~ELSE+always @(posedge ~ARG[2]) begin : ~SYM[2]+  if (~ARG[6]) begin+    ~SYM[0][~ARG[7]] <= ~TOBV[~ARG[8]][~TYP[8]];+  end+  ~SYM[1] <= ~SYM[0][~ARG[5]];+end~FI+assign ~RESULT = ~FROMBV[~SYM[1]][~TYP[8]];+// blockRam end"+  }+}+@++-}++{- $multiclock #multiclock#+Clash supports designs multiple /clock/ (and /reset/) domains, though perhaps in+a slightly limited form. What is possible is:++* Create clock primitives, such as PPLs, which have an accompanying HDL primitive+  (described <#primitives later on> in this tutorial).+* Explicitly assign clocks to memory primitives.+* Synchronize between differently-clocked parts of your design in a type-safe+  way.++What is /not/ possible is:++* Directly generate a clock signal in module A, and assign this clock signal to+  a memory primitive in module B. For example, the following is not possible:++  @+  pow2Clocks+    :: ( 'KnownConfiguration' domIn (''DomainConfiguration' domIn pIn eIn rIn iIn polIn)+       , 'KnownConfiguration' dom2  (''DomainConfiguration' dom2 (2*pIn) e2 r2 i2 p2)+       , 'KnownConfiguration' dom4  (''DomainConfiguration' dom4 (4*pIn) e4 r4 i4 p4)+       , 'KnownConfiguration' dom8  (''DomainConfiguration' dom8 (8*pIn) e8 r8 i8 p8)+       , 'KnownConfiguration' dom16 (''DomainConfiguration' dom16 (16*pIn) e16 r16 i16 p16)+    => 'Clock' domIn+    -> 'Reset' domIn+    -> ( 'Clock' dom16+       , 'Clock' dom8+       , 'Clock' dom4+       , 'Clock' dom2 )+  pow2Clocks clk rst = (cnt!3, cnt!2, cnt!1, cnt!0)+    where+      cnt = 'Clash.Explicit.Signal.register' clk rst 0 (cnt + 1)+  @++  As it is not possible to convert the individual bits to a 'Clock'.++  However! What is possible is to do the following:++  @+  pow2Clocks'+    :: ( 'KnownConfiguration' domIn (''DomainConfiguration' domIn pIn eIn rIn iIn polIn)+       , 'KnownConfiguration' dom2  (''DomainConfiguration' dom2 (2*pIn) e2 r2 i2 p2)+       , 'KnownConfiguration' dom4  (''DomainConfiguration' dom4 (4*pIn) e4 r4 i4 p4)+       , 'KnownConfiguration' dom8  (''DomainConfiguration' dom8 (8*pIn) e8 r8 i8 p8)+       , 'KnownConfiguration' dom16 (''DomainConfiguration' dom16 (16*pIn) e16 r16 i16 p16)+    => 'Clock' domIn+    -> 'Reset' domIn+    -> ( 'Clock' dom16+       , 'Clock' dom8+       , 'Clock' dom4+       , 'Clock' dom2 )+  pow2Clocks' clk rst = ('clockGen', 'clockGen', 'clockGen', 'clockGen')+  {\-\# NOINLINE pow2Clocks' \#-\}+  @++  And then create a HDL primitive, as described in later on in+  this <#primitives tutorial>, to implement the desired behavior in HDL.++What this means is that when Clash converts your design to VHDL/(System)Verilog,+you end up with a top-level module/entity with multiple clock and reset ports+for the different clock domains. If you're targeting an FPGA, you can use e.g. a+<https://www.altera.com/literature/ug/ug_altpll.pdf PPL> or+<http://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf MMCM>+to provide the clock signals.++== Building a FIFO synchronizer++This part of the tutorial assumes you know what <https://en.wikipedia.org/wiki/Metastability_in_electronics metastability>+is, and how it can never truly be avoided in any asynchronous circuit. Also+it assumes that you are familiar with the design of synchronizer circuits, and+why a dual flip-flop synchronizer only works for bit-synchronization and not+word-synchronization.+The explicitly clocked versions of all synchronous functions and primitives can+be found in "Clash.Explicit.Prelude", which also re-exports the functions in+"Clash.Signal.Explicit". We will use those functions to create a FIFO where+the read and write port are synchronized to different clocks. Below you can find+the code to build the FIFO synchronizer based on the design described in:+<http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf>++We start with enable a few options that will make writing the type-signatures for+our components a bit easier. Instead of importing the standard "Clash.Prelude"+module, we will import the "Clash.Explicit.Prelude" module where all our clocks+and resets must be explicitly routed (other imports will be used later):++@+module MultiClockFifo where++import "Clash.Explicit.Prelude"+import "Clash.Prelude"          (mux)+import Data.Maybe             (isJust)+import Data.Constraint        (Dict (..), (:-)( Sub ))+import Data.Constraint.Nat    (leTrans)+@++Then we'll start with the /heart/ of the FIFO synchronizer, an asynchronous RAM+in the form of 'asyncRam'. It's called an asynchronous RAM because the read+port is not synchronized to any clock (though the write port is). Note that in+Clash we don't really have asynchronous logic, there is only combinational and+synchronous logic. As a consequence, we see in the type signature of+'Clash.Explicit.Prelude.asyncRam':++@+__asyncRam__+  :: ( 'Enum' addr+     , 'HasCallStack'+     , 'KnownDomain' wdom wconf+     , 'KnownDomain' rdom rconf+     )+  => 'Clock' wdom                     -- ^ Clock to which to synchronize the write port of the RAM+  -> 'Clock' rdom                     -- ^ 'Clock' to which the read address signal, @r@, is synchronized to+  -> 'Enable' wdom                    -- ^ Global enable+  -> 'SNat' n                         -- ^ Size @n@ of the RAM+  -> 'Signal' rdom addr               -- ^ Read address @r@+  -> 'Signal' wdom (Maybe (addr, a))  -- ^ (write address @w@, value to write)+  -> 'Signal' rdom a                  -- ^ Value of the @RAM@ at address @r@+@++that the signal containing the read address __r__ is synchronized to a different+clock. That is, there is __no__ such thing as an @AsyncSignal@ in Clash.++We continue by instantiating the 'Clash.Explicit.Prelude.asyncRam':++@+fifoMem wclk rclk en addrSize\@SNat full raddr writeM =+  'Clash.Explicit.Prelude.asyncRam'+    wclk rclk en+    ('pow2SNat' addrSize)+    raddr+    ('mux' full (pure Nothing) writeM)+@++We see that we give it @2^addrSize@ elements, where @addrSize@ is the bit-size+of the address. Also, we only write new values to the RAM when a new write is+requested, indicated by @wdataM@ having a 'Data.Maybe.Just' value, and the+buffer is not full, indicated by @wfull@.++The next part of the design calculates the read and write address for the+asynchronous RAM, and creates the flags indicating whether the FIFO is full+or empty. The address and flag generator is given in 'mealy' machine style:++@+ptrCompareT+  :: SNat addrSize+  -> (BitVector (addrSize + 1) -> BitVector (addrSize + 1) -> Bool)+  -> ( BitVector (addrSize + 1)+     , BitVector (addrSize + 1)+     , Bool )+  -> ( BitVector (addrSize + 1)+     , Bool )+  -> ( ( BitVector (addrSize + 1)+       , BitVector (addrSize + 1)+       , Bool )+     , ( Bool+       , BitVector addrSize+       , BitVector (addrSize + 1)+       )+     )+ptrCompareT addrSize\@SNat flagGen (bin, ptr, flag) (s_ptr, inc) =+  ( (bin', ptr', flag')+  , (flag, addr, ptr) )+ where+  -- GRAYSTYLE2 pointer+  bin' = bin + 'boolToBV' (inc && not flag)+  ptr' = (bin' \`shiftR\` 1) \`xor\` bin'+  addr = 'truncateB' bin+  flag' = flagGen ptr' s_ptr+@++It is parametrized in both address size, @addrSize@, and status flag generator,+@flagGen@. It has two inputs, @s_ptr@, the synchronized pointer from the other+clock domain, and @inc@, which indicates we want to perform a write or read of+the FIFO. It creates three outputs: @flag@, the full or empty flag, @addr@, the+read or write address into the RAM, and @ptr@, the Gray-encoded version of the+read or write address which will be synchronized between the two clock domains.++Next follow the initial states of address generators, and the flag generators+for the empty and full flags:++@+-- FIFO empty: when next pntr == synchronized wptr or on reset+isEmpty       = (==)+rptrEmptyInit = (0, 0, True)++-- FIFO full: when next pntr == synchronized {~wptr[addrSize:addrSize-1],wptr[addrSize-2:0]}+isFull+  :: forall addrSize+   . (2 <= addrSize)+  => 'SNat' addrSize+  -> 'BitVector' (addrSize + 1)+  -> 'BitVector' (addrSize + 1)+  -> Bool+isFull addrSize\@SNat ptr s_ptr = case leTrans \@1 \@2 \@addrSize of+  Sub Dict ->+    let a1 = 'SNat' \@(addrSize - 1)+        a2 = 'SNat' \@(addrSize - 2)+    in  ptr == ('complement' ('slice' addrSize a1 s_ptr) '++#' 'slice' a2 d0 s_ptr)++wptrFullInit = (0, 0, False)+@++We create a dual flip-flop synchronizer to be used to synchronize the+Gray-encoded pointers between the two clock domains:++@+ptrSync clk1 clk2 rst2 =+  'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.unsafeSynchronizer' clk1 clk2+@++It uses the 'unsafeSynchronizer' primitive, which is needed to go from one clock+domain to the other. All synchronizers are specified in terms of+'unsafeSynchronizer' (see for example the <src/Clash-Prelude-RAM.html#line-103 source of asyncRam>).+The 'unsafeSynchronizer' primitive is turned into a (bundle of) wire(s) by the+Clash compiler, so developers must ensure that it is only used as part of a+proper synchronizer.++Finally we combine all the component in:++@+asyncFIFOSynchronizer+  :: ( 'KnownDomain' wdom wconf+     , 'KnownDomain' rdom rconf+     , 2 <= addrSize )+  => SNat addrSize+  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@+  -- elements.+  -> 'Clock' wdom+  -- ^ 'Clock' to which the write port is synchronized+  -> 'Clock' rdom+  -- ^ 'Clock' to which the read port is synchronized+  -> 'Reset' wdom+  -> 'Reset' rdom+  -> 'Enable' wdom+  -> 'Enable' rdom+  -> 'Signal' rdom Bool+  -- ^ Read request+  -> 'Signal' wdom (Maybe a)+  -- ^ Element to insert+  -> ('Signal' rdom a, 'Signal' rdom Bool, 'Signal' wdom Bool)+  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)+asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst wen ren rinc wdataM =+  (rdata, rempty, wfull)+ where+  s_rptr = 'dualFlipFlopSynchronizer' rclk wclk wrst wen 0 rptr+  s_wptr = 'dualFlipFlopSynchronizer' wclk rclk rrst ren 0 wptr++  rdata =+    fifoMem+      wclk rclk wen+      addrSize wfull raddr+      (liftA2 (,) \<$\> (pure \<$\> waddr) \<*\> wdataM)++  (rempty, raddr, rptr) =+    'mealyB'+      rclk rrst ren+      (ptrCompareT addrSize (==))+      (0, 0, True)+      (s_wptr, rinc)++  (wfull, waddr, wptr) =+    'mealyB'+      wclk wrst wen+      (ptrCompareT addrSize (isFull addrSize))+      (0, 0, False)+      (s_rptr, isJust \<$\> wdataM)+@++where we first specify the synchronization of the read and the write pointers,+instantiate the asynchronous RAM, and instantiate the read address \/ pointer \/+flag generator and write address \/ pointer \/ flag generator.++Ultimately, the whole file containing our FIFO design will look like this:++@+module MultiClockFifo where++import "Clash.Explicit.Prelude"+import "Clash.Prelude"          (mux)+import Data.Maybe             (isJust)+import Data.Constraint        (Dict (..), (:-)( Sub ))+import Data.Constraint.Nat    (leTrans)++fifoMem wclk rclk en addrSize\@SNat full raddr writeM =+  'Clash.Explicit.Prelude.asyncRam'+    wclk rclk en+    ('pow2SNat' addrSize)+    raddr+    ('mux' full (pure Nothing) writeM)++ptrCompareT+  :: SNat addrSize+  -> (BitVector (addrSize + 1) -> BitVector (addrSize + 1) -> Bool)+  -> ( BitVector (addrSize + 1)+     , BitVector (addrSize + 1)+     , Bool )+  -> ( BitVector (addrSize + 1)+     , Bool )+  -> ( ( BitVector (addrSize + 1)+       , BitVector (addrSize + 1)+       , Bool )+     , ( Bool+       , BitVector addrSize+       , BitVector (addrSize + 1)+       )+     )+ptrCompareT addrSize\@SNat flagGen (bin, ptr, flag) (s_ptr, inc) =+  ( (bin', ptr', flag')+  , (flag, addr, ptr) )+ where+  -- GRAYSTYLE2 pointer+  bin' = bin + 'boolToBV' (inc && not flag)+  ptr' = (bin' \`shiftR\` 1) \`xor\` bin'+  addr = 'truncateB' bin++  flag' = flagGen ptr' s_ptr++-- FIFO empty: when next pntr == synchronized wptr or on reset+isEmpty       = (==)+rptrEmptyInit = (0, 0, True)++-- FIFO full: when next pntr == synchronized {~wptr[addrSize:addrSize-1],wptr[addrSize-2:0]}+isFull+  :: forall addrSize+   . (2 <= addrSize)+  => 'SNat' addrSize+  -> 'BitVector' (addrSize + 1)+  -> 'BitVector' (addrSize + 1)+  -> Bool+isFull addrSize\@SNat ptr s_ptr = case leTrans \@1 \@2 \@addrSize of+  Sub Dict ->+    let a1 = 'SNat' \@(addrSize - 1)+        a2 = 'SNat' \@(addrSize - 2)+    in  ptr == ('complement' ('slice' addrSize a1 s_ptr) '++#' 'slice' a2 d0 s_ptr)++wptrFullInit = (0, 0, False)++-- Dual flip-flop synchronizer+ptrSync clk1 clk2 rst2 =+  'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.register' clk2 rst2 0 . 'Clash.Explicit.Signal.unsafeSynchronizer' clk1 clk2++-- Async FIFO synchronizer+asyncFIFOSynchronizer+  :: ( 'KnownDomain' wdom wconf+     , 'KnownDomain' rdom rconf+     , 2 <= addrSize )+  => SNat addrSize+  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@+  -- elements.+  -> 'Clock' wdom+  -- ^ Clock to which the write port is synchronized+  -> 'Clock' rdom+  -- ^ Clock to which the read port is synchronized+  -> 'Reset' wdom+  -> 'Reset' rdom+  -> 'Enable' wdom+  -> 'Enable' rdom+  -> 'Signal' rdom Bool+  -- ^ Read request+  -> 'Signal' wdom (Maybe a)+  -- ^ Element to insert+  -> ('Signal' rdom a, 'Signal' rdom Bool, 'Signal' wdom Bool)+  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)+asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst wen ren rinc wdataM =+  (rdata, rempty, wfull)+ where+  s_rptr = 'dualFlipFlopSynchronizer' rclk wclk wrst wen 0 rptr+  s_wptr = 'dualFlipFlopSynchronizer' wclk rclk rrst ren 0 wptr++  rdata =+    fifoMem+      wclk rclk wen+      addrSize wfull raddr+      (liftA2 (,) \<$\> (pure \<$\> waddr) \<*\> wdataM)++  (rempty, raddr, rptr) =+    'mealyB'+      rclk rrst ren+      (ptrCompareT addrSize (==))+      (0, 0, True)+      (s_wptr, rinc)++  (wfull, waddr, wptr) =+    'mealyB'+      wclk wrst wen+      (ptrCompareT addrSize (isFull addrSize))+      (0, 0, False)+      (s_rptr, isJust \<$\> wdataM)+@++== Instantiating a FIFO synchronizer++Having finished our FIFO synchronizer it's time to instantiate with concrete+clock domains. Let us assume we have part of our system connected to an ADC+which runs at 20 MHz, and we have created an FFT component running at only 9+MHz. We want to connect part of our design connected to the ADC, and running+at 20 MHz, to part of our design connected to the FFT running at 9 MHz.++We can calculate the clock periods using 'hzToPeriod':++>>> hzToPeriod 20e6+50000+>>> hzToPeriod 9e6+111112++We can then create the clock and reset domains:++@+'createDomain' vSystem{vName=\"ADC\", vPeriod=hzToPeriod 20e6}+'createDomain' vSystem{vName=\"FFT\", vPeriod=hzToPeriod 9e6}+@++and subsequently a 256-space FIFO synchronizer that safely bridges the ADC clock+domain and to the FFT clock domain:++@+adcToFFT+  :: 'Clock' \"ADC\"+  -> 'Clock' \"FFT\"+  -> 'Reset' \"ADC\"+  -> 'Reset' \"FFT\"+  -> 'Signal' \"FFT\" Bool+  -> 'Signal' \"ADC\" (Maybe (SFixed 8 8))+  -> ( 'Signal' \"FFT\" (SFixed 8 8)+     , 'Signal' \"FFT\" Bool+     , 'Signal' \"ADC\" Bool )+adcToFFT = asyncFIFOSynchronizer d8+@++-}++{- $conclusion+For now, this is the end of this tutorial. We will be adding updates over time,+so check back from time to time. We recommend that you continue with+exploring the "Clash.Prelude" module, and get a better understanding of the+capabilities of Clash in the process.+-}++{- $errorsandsolutions+A list of often encountered errors and their solutions:++* __Type error: Couldn't match expected type @'Signal' dom (a,b)@ with actual type__+  __@('Signal' dom a, 'Signal' dom b)@__:++    Signals of product types and product types (to which tuples belong) of+    signals are __isomorphic__ due to synchronisity principle, but are not+    (structurally) equal. Use the 'bundle' function to convert from a product type+    to the signal type. So if your code which gives the error looks like:++    @+    ... = f a b (c,d)+    @++    add the 'bundle' function like so:++    @+    ... = f a b ('bundle' (c,d))+    @++    Product types supported by 'bundle' are:++    * All tuples up to and including 62-tuples (GHC limit)+    * The 'Vec'tor type++* __Type error: Couldn't match expected type @('Signal' dom a, 'Signal' dom b)@ with__+  __ actual type @'Signal' dom (a,b)@__:++    Product types (to which tuples belong) of signals and signals of product+    types are __isomorphic__ due to synchronicity principle, but are not+    (structurally) equal. Use the 'unbundle' function to convert from a signal+    type to the product type. So if your code which gives the error looks like:++    @+    (c,d) = f a b+    @++    add the 'unbundle' function like so:++    @+    (c,d) = 'unbundle' (f a b)+    @++    Product types supported by 'unbundle' are:++    * All tuples up to and including 62-tuples (GHC limit)+    * The 'Vec'tor type++* __Clash.Netlist(..): Not in normal form: \<REASON\>: \<EXPR\>__:++    A function could not be transformed into the expected normal form. This+    usually means one of the following:++    * The @topEntity@ has residual polymorphism.+    * The @topEntity@ has higher-order arguments, or a higher-order result.+    * You are using types which cannot be represented in hardware.++    The solution for all the above listed reasons is quite simple: remove them.+    That is, make sure that the @topEntity@ is completely monomorphic and+    first-order. Also remove any variables and constants/literals that have a+    non-representable type, see <#unsupported Unsupported Haskell features> to+    find out which types are not representable.++* __Clash.Normalize(94): Expr belonging to bndr: \<FUNCTION\> remains__+  __recursive after normalization__:++    * If you actually wrote a recursive function, rewrite it to a non-recursive+      one using e.g. one of the higher-order functions in "Clash.Sized.Vector" :-)++    * You defined a recursively defined value, but left it polymorphic:++    @+    topEntity x y = acc+      where+        acc = 'register' 3 (acc + x * y)+    @++    The above function, works for any number-like type. This means that @acc@ is+    a recursively defined __polymorphic__ value. Adding a monomorphic type+    annotation makes the error go away:++    @+    topEntity+      :: 'SystemClockReset'+      => 'Signal' 'System' ('Signed' 8)+      -> 'Signal' 'System' ('Signed' 8)+      -> 'Signal' 'System' ('Signed' 8)+    topEntity x y = acc+      where+        acc = 'register' 3 (acc + x * y)+    @++* __Clash.Normalize.Transformations(155): InlineNonRep: \<FUNCTION\> already__+  __inlined 100 times in:\<FUNCTION\>, \<TYPE\>__:++    You left the @topEntity@ function polymorphic or higher-order: use+    @:t topEntity@ to check if the type is indeed polymorphic or higher-order.+    If it is, add a monomorphic type signature, and / or supply higher-order+    arguments.++*  __\<*** Exception: \<\<loop\>\>__ or "blinking cursor"++    You are using value-recursion, but one of the 'Vec'tor functions that you+    are using is too /strict/ in one of the recursive arguments. For example:++    @+    -- Bubble sort for 1 iteration+    sortV xs = 'map' fst sorted ':<' (snd ('last' sorted))+     where+       lefts  = 'head' xs :> 'map' snd ('init' sorted)+       rights = 'tail' xs+       sorted = 'zipWith' compareSwapL lefts rights++    -- Compare and swap+    compareSwapL a b = if a < b then (a,b)+                                else (b,a)+    @++    Will not terminate because 'zipWith' is too strict in its second argument.++    In this case, adding 'lazyV' on 'zipWith's second argument:++    @+    sortVL xs = 'map' fst sorted ':<' (snd ('last' sorted))+     where+       lefts  = 'head' xs :> map snd ('init' sorted)+       rights = 'tail' xs+       sorted = 'zipWith' compareSwapL ('lazyV' lefts) rights+    @++    Results in a successful computation:++    >>> sortVL (4 :> 1 :> 2 :> 3 :> Nil)+    <1,2,3,4>+-}++{- $limitations #limitations#+Here is a list of Haskell features for which the Clash compiler has only+/limited/ support (for now):++* __Recursively defined functions__++    At first hand, it seems rather bad that a compiler for a functional language+    cannot synthesize recursively defined functions to circuits. However, when+    viewing your functions as a /structural/ specification of a circuit, this+    /feature/ of the Clash compiler makes sense. Also, only certain types of+    recursion are considered non-synthesizable; recursively defined values are+    for example synthesizable: they are (often) synthesized to feedback loops.++    Let us distinguish between three variants of recursion:++    * __Dynamic data-dependent recursion__++        As demonstrated in this definition of a function that calculates the+        n'th Fibbonacci number:++        @+        fibR 0 = 0+        fibR 1 = 1+        fibR n = fibR (n-1) + fibR (n-2)+        @++        To get the first 10 numbers, we do the following:++        >>> import qualified Data.List as L+        >>> L.map fibR [0..9]+        [0,1,1,2,3,5,8,13,21,34]++        The @fibR@ function is not synthesizable by the Clash compiler, because,+        when we take a /structural/ view, @fibR@ describes an infinitely deep+        structure.++        In principal, descriptions like the above could be synthesized to a+        circuit, but it would have to be a /sequential/ circuit. Where the most+        general synthesis would then require a stack. Such a synthesis approach+        is also known as /behavioral/ synthesis, something which the Clash+        compiler simply does not do. One reason that Clash does not do this is+        because it does not fit the paradigm that only functions working on+        values of type 'Signal' result in sequential circuits, and all other+        (non higher-order) functions result in combinational circuits. This+        paradigm gives the designer the most straightforward mapping from the+        original Haskell description to generated circuit, and thus the greatest+        control over the eventual size of the circuit and longest propagation+        delay.++    * __Value-recursion__++        As demonstrated in this definition of a function that calculates the+        n'th Fibbonaci number on the n'th clock cycle:++        @+        fibS = r+          where r = 'register' 0 r + 'register' 0 ('register' 1 r)+        @++        To get the first 10 numbers, we do the following:++        >>> sampleN @System 11 fibS+        [0,0,1,1,2,3,5,8,13,21,34]++        Unlike the @fibR@ function, the above @fibS@ function /is/ synthesizable+        by the Clash compiler. Where the recursively defined (non-function)+        value /r/ is synthesized to a feedback loop containing three registers+        and one adder.++        Note that not all recursively defined values result in a feedback loop.+        An example that uses recursively defined values which does not result+        in a feedback loop is the following function that performs one iteration+        of bubble sort:++        @+        sortV xs = 'map' fst sorted :< (snd ('last' sorted))+         where+           lefts  = 'head' xs :> 'map' snd ('init' sorted)+           rights = 'tail' xs+           sorted = 'zipWith' compareSwapL lefts rights+        @++        Where we can clearly see that 'lefts' and 'sorted' are defined in terms+        of each other. Also the above @sortV@ function /is/ synthesizable.++    * __Static/Structure-dependent recursion__++        Static, or, structure-dependent recursion is a rather /vague/ concept.+        What we mean by this concept are recursive definitions where a user can+        sensibly imagine that the recursive definition can be completely+        unfolded (all recursion is eliminated) at compile-time in a finite+        amount of time.++        Such definitions would e.g. be:++        @+        mapV :: (a -> b) -> Vec n a -> Vec n b+        mapV _ Nil         = Nil+        mapV f (Cons x xs) = Cons (f x) (mapV f xs)++        topEntity :: Vec 4 Int -> Vec 4 Int+        topEntity = mapV (+1)+        @++        Where one can imagine that a compiler can unroll the definition of+        @mapV@ four times, knowing that the @topEntity@ function applies @mapV@+        to a 'Vec' of length 4. Sadly, the compile-time evaluation mechanisms in+        the Clash compiler are very poor, and a user-defined function such as+        the @mapV@ function defined above, is /currently/ not synthesizable.+        We /do/ plan to add support for this in the future. In the mean time,+        this poor support for user-defined recursive functions is amortized by+        the fact that the Clash compiler has built-in support for the+        higher-order functions defined in "Clash.Sized.Vector". Most regular+        design patterns often encountered in circuit design are captured by the+        higher-order functions in "Clash.Sized.Vector".++* __Recursive datatypes__++    The Clash compiler needs to be able to determine a bit-size for any value+    that will be represented in the eventual circuit. More specifically, we need+    to know the maximum number of bits needed to represent a value. While this+    is trivial for values of the elementary types, sum types, and product types,+    putting a fixed upper bound on recursive types is not (always) feasible.+    This means that the ubiquitous list type is unsupported! The only recursive+    types that are currently supported by the Clash compiler is the 'Vec'tor and+    'RTree' types, for which the compiler has hard-coded knowledge.++    For \"easy\" 'Vec'tor literals you should use Template Haskell splices and+    the 'listToVecTH' /meta/-function that as we have seen earlier in this tutorial.++* __GADTs__++    Clash has experimental support for GADTs. Similar to recursive types, Clash+    can't determine bit-sizes of GADTs. Notable exceptions to this rule are+    'Vec' and 'RTree'. You can still use your own GADTs, as long as they can be+    removed through static analysis. For example, the following case will be+    optimized away and is therefore fine to use:++    @+    x =+      case 'resetKind' @@'System' of+        SAsynchronous -> 'a'+        SSynchronous -> 'b'+    @++* __Floating point types__++    There is no support for the 'Float' and 'Double' types, if you need numbers+    with a /fractional/ part you can use the 'Fixed' point type.++    As to why there is no support for these floating point types:++        1.  In order to achieve reasonable operating frequencies, arithmetic+            circuits for floating point data types must be pipelined.+        2.  Haskell's primitive arithmetic operators on floating point data types,+            such as 'plusFloat#'++            @+            __plusFloat#__ :: 'Float#' -> 'Float#' -> 'Float#'+            @++            which underlie @'Float'@'s 'Num' instance, must be implemented as+            purely combinational circuits according to their type. Remember,+            sequential circuits operate on values of type \"@'Signal' a@\".++    Although it is possible to implement purely combinational (not pipelined)+    arithmetic circuits for floating point data types, the circuit would be+    unreasonable slow. And so, without synthesis possibilities for the basic+    arithmetic operations, there is no point in supporting the floating point+    data types.++* __Haskell primitive types__++    Only the following primitive Haskell types are supported:++        * 'Integer'+        * 'Int'+        * 'Int8'+        * 'Int16'+        * 'Int32'+        * 'Int64' (not available when compiling with @-fclash-intwidth=32@ on a 64-bit machine)+        * 'Word'+        * 'Word8'+        * 'Word16'+        * 'Word32'+        * 'Word64' (not available when compiling with @-fclash-intwidth=32@ on a 64-bit machine)+        * 'Char'++    There are several aspects of which you should take note:++        *   'Int' and 'Word' are represented by the same number of bits as is+            native for the architecture of the computer on which the Clash+            compiler is executed. This means that if you are working on a 64-bit+            machine, 'Int' and 'Word' will be 64-bit. This might be problematic+            when you are working in a team, and one designer has a 32-bit+            machine, and the other has a 64-bit machine. In general, you should+            be avoiding 'Int' in such cases, but as a band-aid solution, you can+            force the Clash compiler to use a specific bit-width for `Int` and+            `Word` using the @-fclash-intwidth=N@ flag, where /N/ must either be+            /32/ or /64/.++        *   When you use the @-fclash-intwidth=32@ flag on a /64-bit/ machine,+            the 'Word64' and 'Int64' types /cannot/ be translated. This+            restriction does /not/ apply to the other three combinations of+            @-fclash-intwidth@ flag and machine type.++        *   The translation of 'Integer' is not meaning-preserving. 'Integer' in+            Haskell is an arbitrary precision integer, something that cannot+            be represented in a statically known number of bits. In the Clash+            compiler, we chose to represent 'Integer' by the same number of bits+            as we do for 'Int' and 'Word'. As you have read in a previous+            bullet point, this number of bits is either 32 or 64, depending on+            the architecture of the machine the Clash compiler is running on, or+            the setting of the @-fclash-intwidth@ flag.++            Consequently, you should use `Integer` with due diligence; be+            especially careful when using `fromIntegral` as it does a conversion+            via 'Integer'. For example:++                > signedToUnsigned :: Signed 128 -> Unsigned 128+                > signedToUnsigned = fromIntegral++            can either lose the top 64 or 96 bits depending on whether 'Integer'+            is represented by 64 or 32 bits. Instead, when doing such conversions,+            you should use 'bitCoerce':++                > signedToUnsigned :: Signed 128 -> Unsigned 128+                > signedToUnsigned = bitCoerce++* __Side-effects: 'IO', 'ST', etc.__++    There is no support for side-effecting computations such as those in the+    'IO' or 'ST' monad. There is also no support for Haskell's+    <http://www.haskell.org/haskellwiki/Foreign_Function_Interface FFI>.+-}++{- $vslava+In Haskell land the most well-known way of describing digital circuits is the+Lava family of languages:++* <http://hackage.haskell.org/package/chalmers-lava2000 Chalmers Lava>+* <http://hackage.haskell.org/package/xilinx-lava Xilinx Lava>+* <http://hackage.haskell.org/package/york-lava York Lava>+* <http://hackage.haskell.org/package/kansas-lava Kansas Lava>++The big difference between Clash and Lava is that Clash uses a \"standard\"+compiler (static analysis) approach towards synthesis, where Lava is an+embedded domain specific language. One downside of static analysis vs. the+embedded language approach is already clearly visible: synthesis of recursive+descriptions does not come for \"free\". This will be implemented in Clash in+due time, but that doesn't help the circuit designer right now. As already+mentioned earlier, the poor support for recursive functions is amortized by+the built-in support for the higher-order in "Clash.Sized.Vector".++The big upside of Clash and its static analysis approach is that Clash can+do synthesis of \"normal\" functions: there is no forced encasing datatype (often+called /Signal/ in Lava) on all the arguments and results of a synthesizable+function. This enables the following features not available to Lava:++* Automatic synthesis for user-defined ADTs+* Synthesis of all choice constructs (pattern matching, guards, etc.)+* 'Applicative' instance for the 'Signal' type+* Working with \"normal\" functions permits the use of e.g. the+  'Control.Monad.State.Lazy.State' monad to describe the functionality of a+  circuit.++Although there are Lava alternatives to some of the above features (e.g.+first-class patterns to replace pattern matching) they are not as \"beautiful\"+and / or easy to use as the standard Haskell features.+-}++{- $migration++* Clash has overhauled the way synthesis options are represented. You can read+  about this change in the blogpost: <https://clash-lang.org/blog/0005-synthesis-domain/ New feature: configurable initial values>.+  The executive summary is as follows:+++------------------------------------------------------------------------------+--------------------------------------------------------------------++| __0.99__                                                                     | __1.0__                                                            |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @topEntity (clk::Clock d 'Source) rst = withClockReset f clk  rst@           | @topEntity clk rst = withClockResetEnable clk rst enableGen f@     |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @topEntity (clk::Clock d 'Gated) rst  = withClockReset f clk  rst@           | @topEntity clk rst enable = withClockResetEnable clk rst enable f@ |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @data A = ... @ (and @A@ is used as state, for example in register or mealy) | @data A = ... deriving (Generic,NFDataX)@                          |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @SystemClockReset@                                                           | @SystemClockResetEnable@                                           |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @HiddenClockReset dom gated sync@                                            | @HiddenClockResetEnable dom@                                       |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @HiddenClock dom gated@                                                      | @HiddenClock dom@                                                  |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @HiddenReset dom sync@                                                       | @HiddenReset dom@                                                  |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @Clock dom gated@                                                            | @Clock dom@                                                        |++------------------------------------------------------------------------------+--------------------------------------------------------------------++| @Reset dom sync@                                                             | @Reset dom@                                                        |++------------------------------------------------------------------------------+--------------------------------------------------------------------+++* @outputVerifier@ now operates on two domains. If you only need one, simply+  change it to @outputVerifier'@++* For an overview of all other changes, check out <https://github.com/clash-lang/clash-compiler/blob/1.0/clash-ghc/CHANGELOG.md the changelog>++=== Examples++==== FIR filter++FIR filter in Clash 1.0:++@+module FIR where++import Clash.Prelude+import Clash.Explicit.Testbench++dotp :: SaturatingNum a+     => Vec (n + 1) a+     -> Vec (n + 1) a+     -> a+dotp as bs = fold boundedPlus (zipWith boundedMult as bs)++fir+  :: (Default a, KnownNat n, SaturatingNum a, HiddenClockReset domain gated synchronous)+  => Vec (n + 1) a -> Signal domain a -> Signal domain a+fir coeffs x_t = y_t+  where+    y_t = dotp coeffs \<$\> bundle xs+    xs  = window x_t++topEntity+  :: Clock  System Source+  -> Reset  System Asynchronous+  -> Signal System (Signed 16)+  -> Signal System (Signed 16)+topEntity = exposeClockReset (fir (2:>3:>(-2):>8:>Nil))+{-# NOINLINE topEntity #-}++testBench :: Signal System Bool+testBench = done+  where+    testInput      = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)+    expectedOutput = outputVerifier clk rst (4:>12:>1:>20:>Nil)+    done           = expectedOutput (topEntity clk rst testInput)+    clk            = tbSystemClockGen (not \<$\> done)+    rst            = systemResetGen+@++FIR filter in current version:++@++module FIR where++import Clash.Prelude+import Clash.Explicit.Testbench++dotp :: SaturatingNum a+     => Vec (n + 1) a+     -> Vec (n + 1) a+     -> a+dotp as bs = fold boundedAdd (zipWith boundedMul as bs)++fir+  :: ( HiddenClockResetEnable dom+     , Default a+     , KnownNat n+     , SaturatingNum a+     , NFDataX a )+  => Vec (n + 1) a -> Signal tag a -> Signal tag a+fir coeffs x_t = y_t+  where+    y_t = dotp coeffs \<$\> bundle xs+    xs  = window x_t++topEntity+  :: Clock  System+  -> Reset  System+  -> Enable System+  -> Signal System (Signed 16)+  -> Signal System (Signed 16)+topEntity = exposeClockResetEnable (fir (2:>3:>(-2):>8:>Nil))+{-# NOINLINE topEntity #-}++testBench :: Signal System Bool+testBench = done+  where+    testInput      = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)+    expectedOutput = outputVerifier' clk rst (4:>12:>1:>20:>Nil)+    done           = expectedOutput (topEntity clk rst enableGen testInput)+    clk            = tbSystemClockGen (not \<$\> done)+    rst            = systemResetGen+@++==== Blinker circuit++Blinker circuit in Clash 0.99:++@+{-# LANGUAGE NoMonoLocalBinds #-}+module Blinker where++import Clash.Prelude+import Clash.Promoted.Symbol+import Clash.Intel.ClockGen++type Dom50 = Dom \"System\" 20000++{\-\# ANN topEntity+  (Synthesize+    { t_name   = \"blinker\"+    , t_inputs = [ PortName \"CLOCK_50\"+                 , PortName \"KEY0\"+                 , PortName \"KEY1\"+                 ]+    , t_output = PortName \"LED\"+    }) \#-\}+topEntity+  :: Clock Dom50 Source+  -> Reset Dom50 Asynchronous+  -> Signal Dom50 Bit+  -> Signal Dom50 (BitVector 8)+topEntity clk rst =+    exposeClockReset (mealy blinkerT (1,False,0) . isRising 1) pllOut rstSync+  where+    (pllOut,pllStable) = altpll \@Dom50 (SSymbol \@ \"altpll50\") clk rst+    rstSync            = resetSynchronizer pllOut (unsafeToAsyncReset pllStable)++blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)+  where+    -- clock frequency = 50e6  (50 MHz)+    -- led update rate = 333e-3 (every 333ms)+    cnt_max = 16650000 -- 50e6 * 333e-3++    cntr' | cntr == cnt_max = 0+          | otherwise       = cntr + 1++    mode' | key1R     = not mode+          | otherwise = mode++    leds' | cntr == 0 = if mode then complement leds+                                else rotateL leds 1+          | otherwise = leds+@++Blinker in Clash 1.0:++@+module Blinker where++import Clash.Prelude+import Clash.Intel.ClockGen++data LedMode+  = Rotate+  -- ^ After some period, rotate active led to the left+  | Complement+  -- ^ After some period, turn on all disable LEDs, and vice versa+  deriving (Generic, 'Undefined')++-- Define a synthesis domain with a clock with a period of 20000 /ps/.+'createDomain' 'vSystem'{vName=\"Input\", vPeriod=20000}++-- Define a synthesis domain with a clock with a period of 50000 /ps/.+'createDomain' 'vSystem'{vName=\"Dom50\", vPeriod=50000}++{\-\# ANN topEntity+  ('Synthesize'+    { t_name   = \"blinker\"+    , t_inputs = [ PortName \"CLOCK_50\"+                 , PortName \"KEY0\"+                 , PortName \"KEY1\"+                 ]+    , t_output = PortName \"LED\"+    }) \#-\}+topEntity+  :: Clock Input+  -- ^ Incoming clock+  -> Signal Input Bool+  -- ^ Reset signal, straight from KEY0+  -> Signal Dom50 Bit+  -- ^ Mode choice, straight from KEY1. See \'LedMode\'.+  -> Signal Dom50 (BitVector 8)+  -- ^ Output containing 8 bits, corresponding to 8 LEDs+topEntity clk20 rstBtn modeBtn =+  exposeClockResetEnable+    (mealy blinkerT initialStateBlinkerT . isRising 1)+    clk50+    rstSync+    en+    modeBtn+ where+  -- | Enable line for subcomponents: we'll keep it always running+  en = enableGen++  -- Start with the first LED turned on, in rotate mode, with the counter on zero+  initialStateBlinkerT = (1, Rotate, 0)++  -- Signal coming from the reset button is low when pressed, and high when+  -- not pressed. We convert this signal to the polarity of our domain with+  -- 'unsafeFromActiveLow'.+  rst = 'Clash.Signal.unsafeFromLowPolarity' rstBtn++  -- Instantiate a PLL: this stabilizes the incoming clock signal and indicates+  -- when the signal is stable. We're also using it to transform an incoming+  -- clock signal running at 20 MHz to a clock signal running at 50 MHz.+  (clk50, pllStable) =+    altpll+      \@Dom50+      (SSymbol \@\"altpll50\")+      clk20+      rst++  -- Synchronize reset to clock signal coming from PLL. We want the reset to+  -- remain active while the PLL is NOT stable, hence the conversion with+  -- 'unsafeFromActiveLow'+  rstSync =+    'Clash.Signal.resetSynchronizer'+      clk50+      (unsafeFromLowPolarity pllStable)+      en++flipMode :: LedMode -> LedMode+flipMode Rotate = Complement+flipMode Complement = Rotate++blinkerT+  :: (BitVector 8, LedMode, Index 16650001)+  -> Bool+  -> ((BitVector 8, LedMode, Index 16650001), BitVector 8)+blinkerT (leds, mode, cntr) key1R = ((leds', mode', cntr'), leds)+  where+    -- clock frequency = 50e6  (50 MHz)+    -- led update rate = 333e-3 (every 333ms)+    cnt_max = 16650000 :: Index 16650001 -- 50e6 * 333e-3++    cntr' | cntr == cnt_max = 0+          | otherwise       = cntr + 1++    mode' | key1R     = flipMode mode+          | otherwise = mode++    leds' | cntr == 0 =+              case mode of+                Rotate -> rotateL leds 1+                Complement -> complement leds+          | otherwise = leds+@ -}
src/Clash/XException.hs view
@@ -1,6 +1,7 @@ {-|-Copyright  :  (C) 2016, University of Twente,-                  2017, Myrtle Software Ltd, QBayLogic, Google Inc.+Copyright  :  (C) 2016,      University of Twente,+                  2017,      QBayLogic, Google Inc.+                  2017-2019, Myrtle Software Ltd License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -14,14 +15,18 @@ "(X,4)" -} -{-# LANGUAGE DefaultSignatures   #-}-{-# LANGUAGE DeriveGeneric       #-}-{-# LANGUAGE FlexibleContexts    #-}-{-# LANGUAGE FlexibleInstances   #-}-{-# LANGUAGE MagicHash           #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StandaloneDeriving  #-}-{-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DefaultSignatures     #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE EmptyCase             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE StandaloneDeriving    #-}+{-# LANGUAGE TypeOperators         #-}  {-# LANGUAGE Trustworthy #-} @@ -29,27 +34,36 @@  module Clash.XException   ( -- * 'X': An exception for uninitialized values-    XException, errorX, isX, maybeX+    XException(..), errorX, isX, hasX, maybeIsX, maybeHasX     -- * Printing 'X' exceptions as \"X\"   , ShowX (..), showsX, printX, showsPrecXWith     -- * Strict evaluation-  , seqX+  , seqX, forceX, deepseqX, rwhnfX, defaultSeqX+    -- * Structured undefined / deep evaluation with undefined values+  , NFDataX (rnfX, deepErrorX)   ) where  import Control.Exception (Exception, catch, evaluate, throw) import Control.DeepSeq   (NFData, rnf) import Data.Complex      (Complex)+import Data.Either       (isLeft)+import Data.Foldable     (toList) import Data.Int          (Int8,Int16,Int32,Int64)-import Data.Ratio        (Ratio)+import Data.Ord          (Down (Down))+import Data.Ratio        (Ratio, numerator, denominator)+import qualified Data.Semigroup as SG+import Data.Sequence     (Seq(Empty, (:<|))) import Data.Word         (Word8,Word16,Word32,Word64) import GHC.Exts          (Char (C#), Double (D#), Float (F#), Int (I#), Word (W#)) import GHC.Generics+import GHC.Natural       (Natural) import GHC.Show          (appPrec)-import GHC.Stack         (HasCallStack, callStack, prettyCallStack)+import GHC.Stack         (HasCallStack, callStack, prettyCallStack, withFrozenCallStack)+import Numeric.Half      (Half) import System.IO.Unsafe  (unsafeDupablePerformIO) --- | An exception representing an \"uninitialised\" value.+-- | An exception representing an \"uninitialized\" value. newtype XException = XException String  instance Show XException where@@ -57,6 +71,17 @@  instance Exception XException +-- | Either 'seqX' or 'deepSeqX' depending on the value of the cabal flag+-- '-fsuper-strict'. If enabled, 'defaultSeqX' will be 'deepseqX', otherwise+-- 'seqX'. Flag defaults to /false/ and thus 'seqX'.+defaultSeqX :: NFDataX a => a -> b -> b+#ifdef CLASH_SUPER_STRICT+defaultSeqX = deepseqX+#else+defaultSeqX = seqX+#endif+{-# INLINE defaultSeqX #-}+ -- | Like 'error', but throwing an 'XException' instead of an 'ErrorCall' -- -- The 'ShowX' methods print these error-values as \"X\"; instead of error'ing@@ -78,22 +103,76 @@ {-# NOINLINE seqX #-} infixr 0 `seqX` --- | Fully evaluate a value, returning 'Nothing' if is throws 'XException'.+-- | Evaluate a value with given function, returning 'Nothing' if it throws+-- 'XException'. ----- > maybeX 42               = Just 42--- > maybeX (XException msg) = Nothing--- > maybeX _|_              = _|_-maybeX :: NFData a => a -> Maybe a-maybeX = either (const Nothing) Just . isX+-- > maybeX hasX 42                  = Just 42+-- > maybeX hasX (XException msg)    = Nothing+-- > maybeX hasX (3, XException msg) = Nothing+-- > maybeX hasX (3, _|_)            = _|_+-- > maybeX hasX _|_                 = _|_+-- >+-- > maybeX isX 42                  = Just 42+-- > maybeX isX (XException msg)    = Nothing+-- > maybeX isX (3, XException msg) = Just (3, XException msg)+-- > maybeX isX (3, _|_)            = Just (3, _|_)+-- > maybeX isX _|_                 = _|_+--+maybeX :: NFData a => (a -> Either String a) -> a -> Maybe a+maybeX f a = either (const Nothing) Just (f a) --- | Fully evaluate a value, returning @'Left' msg@ if is throws 'XException'.+-- | Fully evaluate a value, returning 'Nothing' if it throws 'XException'. ----- > isX 42               = Right 42--- > isX (XException msg) = Left msg--- > isX _|_              = _|_-isX :: NFData a => a -> Either String a-isX a = unsafeDupablePerformIO-  (catch (evaluate (rnf a) >> return (Right a)) (\(XException msg) -> return (Left msg)))+-- > maybeX 42                  = Just 42+-- > maybeX (XException msg)    = Nothing+-- > maybeX (3, XException msg) = Nothing+-- > maybeX (3, _|_)            = _|_+-- > maybeX _|_                 = _|_+--+maybeHasX :: NFData a => a -> Maybe a+maybeHasX = maybeX hasX++-- | Evaluate a value to WHNF, returning 'Nothing' if it throws 'XException'.+--+-- > maybeIsX 42                  = Just 42+-- > maybeIsX (XException msg)    = Nothing+-- > maybeIsX (3, XException msg) = Just (3, XException msg)+-- > maybeIsX (3, _|_)            = Just (3, _|_)+-- > maybeIsX _|_                 = _|_+maybeIsX :: NFData a => a -> Maybe a+maybeIsX = maybeX isX++-- | Fully evaluate a value, returning @'Left' msg@ if it throws 'XException'.+--+-- > hasX 42                  = Right 42+-- > hasX (XException msg)    = Left msg+-- > hasX (3, XException msg) = Left msg+-- > hasX (3, _|_)            = _|_+-- > hasX _|_                 = _|_+--+-- If a data structure contains multiple 'XException's, the "first" message is+-- picked according to the implementation of 'rnf'.+hasX :: NFData a => a -> Either String a+hasX a =+  unsafeDupablePerformIO+    (catch+      (evaluate (rnf a) >> return (Right a))+      (\(XException msg) -> return (Left msg)))+{-# NOINLINE hasX #-}++-- | Evaluate a value to WHNF, returning @'Left' msg@ if is a 'XException'.+--+-- > isX 42                  = Right 42+-- > isX (XException msg)    = Left msg+-- > isX (3, XException msg) = Right (3, XException msg)+-- > isX (3, _|_)            = (3, _|_)+-- > isX _|_                 = _|_+isX :: a -> Either String a+isX a =+  unsafeDupablePerformIO+    (catch+      (evaluate a >> return (Right a))+      (\(XException msg) -> return (Left msg))) {-# NOINLINE isX #-}  showXWith :: (a -> ShowS) -> a -> ShowS@@ -231,6 +310,9 @@ instance ShowX Double where   showsPrecX = showsPrecXWith showsPrec +instance ShowX a => ShowX (Down a) where+  showsPrecX = showsPrecXWith showsPrecX+ instance (ShowX a, ShowX b) => ShowX (Either a b)  instance ShowX Float where@@ -254,6 +336,12 @@ instance ShowX Integer where   showsPrecX = showsPrecXWith showsPrec +instance ShowX Natural where+  showsPrecX = showsPrecXWith showsPrec++instance ShowX a => ShowX (Seq a) where+  showsPrecX _ = showListX . toList+ instance ShowX Word where   showsPrecX = showsPrecXWith showsPrec @@ -358,3 +446,279 @@   gshowsPrecX _ _ (UInt i)    = showsPrec 0 (I# i) . showChar '#' instance GShowX UWord where   gshowsPrecX _ _ (UWord w)   = showsPrec 0 (W# w) . showString "##"++-- | a variant of 'deepseqX' that is useful in some circumstances:+--+-- > forceX x = x `deepseqX` x+forceX :: NFDataX a => a -> a+forceX x = x `deepseqX` x+{-# INLINE forceX #-}++-- | 'deepseqX': fully evaluates the first argument, before returning the+-- second. Does not propagate 'XException's.+deepseqX :: NFDataX a => a -> b -> b+deepseqX a b = rnfX a `seq` b+{-# NOINLINE deepseqX #-}++-- | Reduce to weak head normal form+--+-- Equivalent to @\\x -> 'seqX' x ()@.+--+-- Useful for defining 'NFDataX.rnfX' for types for which NF=WHNF holds.+rwhnfX :: a -> ()+rwhnfX = (`seqX` ())+{-# INLINE rwhnfX #-}++-- | Hidden internal type-class. Adds a generic implementation for the "NFData"+-- part of 'NFDataX'+class GNFDataX arity f where+  grnfX :: RnfArgs arity a -> f a -> ()++instance GNFDataX arity V1 where+  grnfX _ x = case x of {}++data Zero+data One++data RnfArgs arity a where+  RnfArgs0 :: RnfArgs Zero a+  RnfArgs1  :: (a -> ()) -> RnfArgs One a++instance GNFDataX arity U1 where+  grnfX _ u = if isLeft (isX u) then () else case u of U1 -> ()++instance NFDataX a => GNFDataX arity (K1 i a) where+  grnfX _ = rnfX . unK1+  {-# INLINEABLE grnfX #-}++instance GNFDataX arity a => GNFDataX arity (M1 i c a) where+  grnfX args a =+    -- Check for X needed to handle edge-case "data Void"+    if isLeft (isX a) then+      ()+    else+      grnfX args (unM1 a)+  {-# INLINEABLE grnfX #-}++instance (GNFDataX arity a, GNFDataX arity b) => GNFDataX arity (a :*: b) where+  grnfX args xy@(~(x :*: y)) =+    if isLeft (isX xy) then+      ()+    else+      grnfX args x `seq` grnfX args y+  {-# INLINEABLE grnfX #-}++instance (GNFDataX arity a, GNFDataX arity b) => GNFDataX arity (a :+: b) where+  grnfX args lrx =+    if isLeft (isX lrx) then+      ()+    else+      case lrx of+        L1 x -> grnfX args x+        R1 x -> grnfX args x+  {-# INLINEABLE grnfX #-}++instance GNFDataX One Par1 where+  grnfX (RnfArgs1 r) = r . unPar1++instance NFDataX1 f => GNFDataX One (Rec1 f) where+  grnfX (RnfArgs1 r) = liftRnfX r . unRec1++instance (NFDataX1 f, GNFDataX One g) => GNFDataX One (f :.: g) where+  grnfX args = liftRnfX (grnfX args) . unComp1++-- | A class of functors that can be fully evaluated, according to semantics+-- of NFDataX.+class NFDataX1 f where+  -- | 'liftRnfX' should reduce its argument to normal form (that is, fully+  -- evaluate all sub-components), given an argument to reduce @a@ arguments,+  -- and then return '()'.+  --+  -- See 'rnfX' for the generic deriving.+  liftRnfX :: (a -> ()) -> f a -> ()++  default liftRnfX :: (Generic1 f, GNFDataX One (Rep1 f)) => (a -> ()) -> f a -> ()+  liftRnfX r = grnfX (RnfArgs1 r) . from1++-- | Class that houses functions dealing with /undefined/ values in Clash. See+-- 'deepErrorX' and 'rnfX'.+class NFDataX a where+  -- | Create a value where all the elements have an 'errorX', but the spine+  -- is defined.+  deepErrorX :: HasCallStack => String -> a++  default deepErrorX :: (HasCallStack, Generic a, GDeepErrorX (Rep a)) => String -> a+  deepErrorX = withFrozenCallStack $ to . gDeepErrorX++  -- | Evaluate a value to NF. As opposed to 'NFData's 'rnf', it does not bubble+  -- up 'XException's.+  rnfX :: a -> ()++  default rnfX :: (Generic a, GNFDataX Zero (Rep a)) => a -> ()+  rnfX = grnfX RnfArgs0 . from++instance NFDataX ()+instance (NFDataX a, NFDataX b) => NFDataX (a,b)+instance (NFDataX a, NFDataX b, NFDataX c) => NFDataX (a,b,c)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d) => NFDataX (a,b,c,d)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e) => NFDataX (a,b,c,d,e)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e ,NFDataX f)+  => NFDataX (a,b,c,d,e,f)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g)+  => NFDataX (a,b,c,d,e,f,g)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h)+  => NFDataX (a,b,c,d,e,f,g,h)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i)+  => NFDataX (a,b,c,d,e,f,g,h,i)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j)+  => NFDataX (a,b,c,d,e,f,g,h,i,j)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j+         ,NFDataX k)+  => NFDataX (a,b,c,d,e,f,g,h,i,j,k)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j+         ,NFDataX k, NFDataX l)+  => NFDataX (a,b,c,d,e,f,g,h,i,j,k,l)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j+         ,NFDataX k, NFDataX l, NFDataX m)+  => NFDataX (a,b,c,d,e,f,g,h,i,j,k,l,m)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j+         ,NFDataX k, NFDataX l, NFDataX m, NFDataX n)+  => NFDataX (a,b,c,d,e,f,g,h,i,j,k,l,m,n)+instance (NFDataX a, NFDataX b, NFDataX c, NFDataX d, NFDataX e+         ,NFDataX f, NFDataX g, NFDataX h, NFDataX i, NFDataX j+         ,NFDataX k, NFDataX l, NFDataX m, NFDataX n, NFDataX o)+  => NFDataX (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)++instance NFDataX b => NFDataX (a -> b) where+  deepErrorX = pure . deepErrorX+  rnfX = rwhnfX++instance NFDataX a => NFDataX (Down a) where+  deepErrorX = Down . deepErrorX+  rnfX d@(~(Down x))= if isLeft (isX d) then rnfX x else ()++instance NFDataX Bool+instance NFDataX a => NFDataX [a]+instance (NFDataX a, NFDataX b) => NFDataX (Either a b)+instance NFDataX a => NFDataX (Maybe a)++instance NFDataX Char where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Double where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Float where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Int where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Int8 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Int16 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Int32 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Int64 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Integer where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Natural where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Word where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Word8 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Word16 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Word32 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Word64 where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX Half where+  deepErrorX = errorX+  rnfX = rwhnfX++instance NFDataX a => NFDataX (Seq a) where+  deepErrorX = errorX+  rnfX s =+    if isLeft (isX s) then () else go s+   where+    go Empty = ()+    go (x :<| xs) = rnfX x `seq` go xs++instance NFDataX a => NFDataX (Ratio a) where+  deepErrorX = errorX+  rnfX r = rnfX (numerator r) `seq` rnfX (denominator r)++instance NFDataX a => NFDataX (Complex a) where+  deepErrorX = errorX++instance (NFDataX a, NFDataX b) => NFDataX (SG.Arg a b)+instance NFDataX (SG.All)+instance NFDataX (SG.Any)+instance NFDataX a => NFDataX (SG.Dual a)+instance NFDataX a => NFDataX (SG.Endo a)+instance NFDataX a => NFDataX (SG.First a)+instance NFDataX a => NFDataX (SG.Last a)+instance NFDataX a => NFDataX (SG.Max a)+instance NFDataX a => NFDataX (SG.Min a)+instance NFDataX a => NFDataX (SG.Option a)+instance NFDataX a => NFDataX (SG.Product a)+instance NFDataX a => NFDataX (SG.Sum a)++class GDeepErrorX f where+  gDeepErrorX :: HasCallStack => String -> f a++instance GDeepErrorX V1 where+  gDeepErrorX = errorX++instance GDeepErrorX U1 where+  gDeepErrorX = const U1++instance (GDeepErrorX a) => GDeepErrorX (M1 m d a) where+  gDeepErrorX e = M1 (gDeepErrorX e)++instance (GDeepErrorX f, GDeepErrorX g) => GDeepErrorX (f :*: g) where+  gDeepErrorX e = gDeepErrorX e :*: gDeepErrorX e++instance NFDataX c => GDeepErrorX (K1 i c) where+  gDeepErrorX e = K1 (deepErrorX e)++instance GDeepErrorX (f :+: g) where+  gDeepErrorX = errorX
src/Clash/Xilinx/ClockGen.hs view
@@ -6,11 +6,13 @@ PLL and other clock-related components for Xilinx FPGAs -} -{-# LANGUAGE DataKinds      #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE GADTs          #-}+{-# LANGUAGE DataKinds        #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ExplicitForAll   #-}+{-# LANGUAGE GADTs            #-} module Clash.Xilinx.ClockGen where +import Clash.Annotations.Primitive    (hasBlackBox) import Clash.Promoted.Symbol import Clash.Signal.Internal import Unsafe.Coerce@@ -35,23 +37,26 @@ -- clockWizard @@Dom100MHz (SSymbol @@"clkWizard50to100") clk50 rst -- @ clockWizard-  :: forall pllOut pllIn name-   . SSymbol name+  :: forall domIn domOut periodIn periodOut edge init polarity name+   . ( KnownConfiguration domIn  ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity)+     , KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity) )+  => SSymbol name   -- ^ Name of the component, must correspond to the name entered in the   -- \"Clock Wizard\" dialog.   --   -- For example, when you entered \"clockWizard50\", instantiate as follows:   --   -- > SSymbol @ "clockWizard50"-  -> Clock  pllIn 'Source+  -> Clock domIn   -- ^ Free running clock (i.e. a clock pin connected to a crystal)-  -> Reset  pllIn 'Asynchronous+  -> Reset domIn   -- ^ Reset for the PLL-  -> (Clock pllOut 'Source, Signal pllOut Bool)+  -> (Clock domOut, Enable domOut)   -- ^ (Stable PLL clock, PLL lock)-clockWizard _ clk (Async rst) =-  (unsafeCoerce (clockGate clk rst), unsafeCoerce rst)+clockWizard _ clk rst =+  (unsafeCoerce clk, unsafeCoerce (toEnable (unsafeToHighPolarity rst))) {-# NOINLINE clockWizard #-}+{-# ANN clockWizard hasBlackBox #-}  -- | A clock source that corresponds to the Xilinx PLL/MMCM component created -- with the \"Clock Wizard\", with settings to provide a stable 'Clock'@@ -73,22 +78,25 @@ -- clockWizardDifferential @@Dom100MHz (SSymbol @@"clkWizardD50to100") clk50N clk50P rst -- @ clockWizardDifferential-  :: forall pllOut pllIn name-   . SSymbol name+  :: forall domIn domOut periodIn periodOut edge init polarity name+   . ( KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity)+     , KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity) )+  => SSymbol name   -- ^ Name of the component, must correspond to the name entered in the   -- \"Clock Wizard\" dialog.   --   -- For example, when you entered \"clockWizardD50\", instantiate as follows:   --   -- > SSymbol @ "clockWizardD50"-  -> Clock pllIn 'Source+  -> Clock domIn   -- ^ Free running clock, negative phase-  -> Clock pllIn 'Source+  -> Clock domIn   -- ^ Free running clock, positive phase-  -> Reset pllIn 'Asynchronous+  -> Reset domIn   -- ^ Reset for the PLL-  -> (Clock pllOut 'Source, Signal pllOut Bool)+  -> (Clock domOut, Enable domOut)   -- ^ (Stable PLL clock, PLL lock)-clockWizardDifferential _name clkP _clkN (Async rst) =-  (unsafeCoerce (clockGate clkP rst), unsafeCoerce rst)+clockWizardDifferential _name (Clock _) (Clock _) rst =+  (Clock SSymbol, unsafeCoerce (toEnable (unsafeToHighPolarity rst))) {-# NOINLINE clockWizardDifferential #-}+{-# ANN clockWizardDifferential hasBlackBox #-}
src/Clash/Xilinx/DDR.hs view
@@ -8,16 +8,21 @@ For general information about DDR primitives see "Clash.Explicit.DDR".  For more information about the Xilinx DDR primitives see:-    * Vivado Design Suite 7 Series FPGA and Zynq-7000 All Programmable SoC-      Libraries Guide, UG953 (v2017.2) June 7, 2016, p294-296,p404-406,-      https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_2/ug953-vivado-7series-libraries.pdf++* Vivado Design Suite 7 Series FPGA and Zynq-7000 All Programmable SoC+  Libraries Guide, UG953 (v2018.3) December 5, 2018, p371-373,p481-483,+  <https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug953-vivado-7series-libraries.pdf> -} +{-# LANGUAGE CPP              #-} {-# LANGUAGE DataKinds        #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MagicHash        #-} {-# LANGUAGE TypeFamilies     #-} {-# LANGUAGE TypeOperators    #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE NoStarIsType #-}+#endif  module Clash.Xilinx.DDR   ( iddr@@ -27,54 +32,63 @@  import GHC.Stack (HasCallStack, withFrozenCallStack) +import Clash.Annotations.Primitive (hasBlackBox) import Clash.Explicit.Prelude import Clash.Explicit.DDR --- | Xilinx specific variant of 'ddrIn' implementend using the Xilinx IDDR--- primitive.+-- | Xilinx specific variant of 'ddrIn' implemented using the Xilinx IDDR+-- primitive in @SAME_EDGE@ mode. -- -- Reset values are @0@ iddr   :: ( HasCallStack-     , fast ~ 'Dom n pFast-     , slow ~ 'Dom n (2*pFast)+     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)      , KnownNat m )-  => Clock slow gated+  => Clock slow   -- ^ clock-  -> Reset slow synchronous+  -> Reset slow   -- ^ reset+  -> Enable slow+  -- ^ global enable   -> Signal fast (BitVector m)   -- ^ DDR input signal   -> Signal slow ((BitVector m),(BitVector m))   -- ^ normal speed output pairs-iddr clk rst = withFrozenCallStack ddrIn# clk rst 0 0 0+iddr clk rst en = withFrozenCallStack ddrIn# clk rst en 0 0 0 {-# NOINLINE iddr #-}+{-# ANN iddr hasBlackBox #-} --- | Xilinx specific variant of 'ddrOut' implementend using the Xilinx ODDR--- primitive.+-- | Xilinx specific variant of 'ddrOut' implemented using the Xilinx ODDR+-- primitive in @SAME_EDGE@ mode. -- -- Reset value is @0@ oddr-  :: ( slow ~ 'Dom n (2*pFast)-     , fast ~ 'Dom n pFast+  :: ( KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)      , KnownNat m )-  => Clock slow gated+  => Clock slow   -- ^ clock-  -> Reset slow synchronous+  -> Reset slow   -- ^ reset-  -> Signal slow (BitVector m,BitVector m)+  -> Enable slow+  -- ^ global enable+  -> Signal slow (BitVector m, BitVector m)   -- ^ normal speed input pairs   -> Signal fast (BitVector m)   -- ^ DDR output signal-oddr clk rst = uncurry (withFrozenCallStack oddr# clk rst) . unbundle+oddr clk rst en = uncurry (withFrozenCallStack oddr# clk rst en) . unbundle -oddr# :: ( slow ~ 'Dom n (2*pFast)-         , fast ~ 'Dom n pFast-         , KnownNat m )-      => Clock slow gated-      -> Reset slow synchronous-      -> Signal slow (BitVector m)-      -> Signal slow (BitVector m)-      -> Signal fast (BitVector m)-oddr# clk rst = ddrOut# clk rst 0+oddr#+  :: ( KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)+     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity)+     , KnownNat m )+  => Clock slow+  -> Reset slow+  -> Enable slow+  -> Signal slow (BitVector m)+  -> Signal slow (BitVector m)+  -> Signal fast (BitVector m)+oddr# clk rst en = ddrOut# clk rst en 0 {-# NOINLINE oddr# #-}+{-# ANN oddr# hasBlackBox #-}
+ src/Language/Haskell/TH/Compat.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE CPP #-}+module Language.Haskell.TH.Compat where+import           Language.Haskell.TH++-- | Compatibility helper to create TySynInstD+mkTySynInstD :: Name -> [Type] -> Type -> Dec+mkTySynInstD tyConNm tyArgs rhs =+#if MIN_VERSION_template_haskell(2,15,0)+        TySynInstD (TySynEqn Nothing+                     (foldl AppT (ConT tyConNm) tyArgs)+                     rhs)+#else+        TySynInstD tyConNm+                   (TySynEqn tyArgs+                             rhs)+#endif
+ tests/Clash/Tests/BitPack.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE CPP            #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-}+{-# LANGUAGE MagicHash      #-}++{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}++module Clash.Tests.BitPack where++import Test.Tasty+import Test.Tasty.HUnit++import Clash.Class.BitPack++import GHC.Generics (Generic)++data Unit    = Unit                        deriving (Generic, BitPack, Eq, Show)+data Wrapper = Wrapper Int                 deriving (Generic, BitPack, Eq, Show)+data Sum     = SumTypeA | SumTypeB         deriving (Generic, BitPack, Eq, Show)+data BigSum  = BS1 | BS2 | BS3 | BS4 | BS5 deriving (Generic, BitPack, Eq, Show)+data Product = Product Int Int             deriving (Generic, BitPack, Eq, Show)+data SP      = S Int Int | P Int           deriving (Generic, BitPack, Eq, Show)+data Rec1    = Rec1 { a :: Int }           deriving (Generic, BitPack, Eq, Show)+data Rec2    = Rec2 { b :: Int, c :: Int } deriving (Generic, BitPack, Eq, Show)++rtt :: (Eq a, Show a, BitPack a) => a -> Assertion+rtt u = unpack (pack u) @?= u++tests :: TestTree+tests =+  testGroup+    "BitPack"+    [ testGroup+        "Generic"+        [ testCase "Unit" (rtt Unit)+        , testCase "Wrapper" (rtt (Wrapper 3))+        , testCase "SumTypeA" (rtt SumTypeA)+        , testCase "SumTypeB" (rtt SumTypeB)+        , testCase "BigSum1" (rtt BS1)+        , testCase "BigSum2" (rtt BS2)+        , testCase "BigSum3" (rtt BS3)+        , testCase "BigSum4" (rtt BS4)+        , testCase "BigSum5" (rtt BS5)+        , testCase "Product" (rtt (Product 3 5))+        , testCase "SP1" (rtt (S 3 5))+        , testCase "SP2" (rtt (P 10))+        , testCase "Rec1" (rtt (Rec1 10))+        , testCase "Rec2" (rtt (Rec2 10 30))+        ]+    ]+
+ tests/Clash/Tests/BitVector.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE BinaryLiterals  #-}+{-# LANGUAGE DataKinds       #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE LambdaCase      #-}+{-# LANGUAGE ViewPatterns    #-}++module Clash.Tests.BitVector where++import Test.Tasty+import Test.Tasty.HUnit++import Clash.Prelude (BitVector, bitPattern)++test1 :: BitVector 8 -> Int+test1 =+  \case+    $(bitPattern "0.......") -> 0+    $(bitPattern "01......") -> 1+    $(bitPattern "11....01") -> 2+    $(bitPattern "11111110") -> 3+    $(bitPattern "........") -> 4+    _                        -> 5  -- To keep exhaustiveness checker happy++tests :: TestTree+tests =+  testGroup+    "bitPattern"+    [ testCase "case0-0" $ test1 0b00000000 @?= 0+    , testCase "case0-1" $ test1 0b00011001 @?= 0+    , testCase "case0-2" $ test1 0b01111111 @?= 0+    , testCase "case0-3" $ test1 0b01100000 @?= 0+    , testCase "case2-0" $ test1 0b11111101 @?= 2+    , testCase "case2-1" $ test1 0b11100001 @?= 2+    , testCase "case3-0" $ test1 0b11111110 @?= 3+    , testCase "case3-1" $ test1 0b11111111 @?= 4+    , testCase "case3-2" $ test1 0b11010110 @?= 4+    ]+
+ tests/Clash/Tests/DerivingDataRepr.hs view
@@ -0,0 +1,121 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BinaryLiterals #-}++module Clash.Tests.DerivingDataRepr where++import Test.Tasty+import Test.Tasty.HUnit+import Prelude ((=<<), ($))+import Clash.Annotations.BitRepresentation+import Clash.Annotations.BitRepresentation.Deriving+import Clash.Tests.DerivingDataReprTypes (Train(..), RGB(..))+import Data.Maybe (Maybe(..))++---------------------------------------------------------+------------ DERIVING SIMPLE REPRESENTATIONS ------------+---------------------------------------------------------+oneHotOverlapRepr :: DataReprAnn+oneHotOverlapRepr = $( (simpleDerivator OneHot OverlapL) =<< [t| Train |] )++oneHotOverlapRepr' :: DataReprAnn+oneHotOverlapRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    8+    [ ConstrRepr 'Passenger   16  16  [0b1100]+    , ConstrRepr 'Freight     32  32  [0b1100, 0b0011]+    , ConstrRepr 'Maintenance 64  64  []+    , ConstrRepr 'Toy         128 128 []+    ]++oneHotWideRepr :: DataReprAnn+oneHotWideRepr = $( (simpleDerivator OneHot Wide) =<< [t| Train |] )++oneHotWideRepr' :: DataReprAnn+oneHotWideRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    10+    [ ConstrRepr 'Passenger   64  64  [0b110000]+    , ConstrRepr 'Freight     128 128 [0b001100, 0b000011]+    , ConstrRepr 'Maintenance 256 256 []+    , ConstrRepr 'Toy         512 512 []+    ]++countOverlapRepr :: DataReprAnn+countOverlapRepr = $( (simpleDerivator Binary OverlapL) =<< [t| Train |] )++countOverlapRepr' :: DataReprAnn+countOverlapRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    6+    [ ConstrRepr 'Passenger   0b110000 0b000000 [0b001100]+    , ConstrRepr 'Freight     0b110000 0b010000 [0b001100,0b000011]+    , ConstrRepr 'Maintenance 0b110000 0b100000 []+    , ConstrRepr 'Toy         0b110000 0b110000 []+    ]++countWideRepr :: DataReprAnn+countWideRepr = $( (simpleDerivator Binary Wide) =<< [t| Train |] )++countWideRepr' :: DataReprAnn+countWideRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    8+    [ ConstrRepr 'Passenger   0b11000000 0b00000000 [0b110000]+    , ConstrRepr 'Freight     0b11000000 0b01000000 [0b001100,0b000011]+    , ConstrRepr 'Maintenance 0b11000000 0b10000000 []+    , ConstrRepr 'Toy         0b11000000 0b11000000 []+    ]++------------------------------------------------+------------ PACKED REPRESENTATIONS ------------+------------------------------------------------++packedRepr :: DataReprAnn+packedRepr = $( packedDerivator =<< [t| Train |] )++packedRepr' :: DataReprAnn+packedRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    5+    [ ConstrRepr 'Freight     0b10000 0 [12,3]+    , ConstrRepr 'Passenger   3       1 [12]+    , ConstrRepr 'Toy         3       2 []+    , ConstrRepr 'Maintenance 3       3 []+    ]++------------------------------------------------------+------------ PACKED MAYBE REPRESENTATIONS ------------+------------------------------------------------------++packedMaybeRGB :: DataReprAnn+packedMaybeRGB = $( packedMaybeDerivator $(defaultDerivator =<< [t| Maybe RGB |]) =<< [t| Maybe RGB |] )++packedMaybeRGB' :: DataReprAnn+packedMaybeRGB' =+  DataReprAnn+    $(liftQ [t| Maybe RGB |])+    2+    [ ConstrRepr 'Nothing 0b11 0b11 []+    , ConstrRepr 'Just    0b00 0b00 [0b11]+    ]++-- MAIN+tests :: TestTree+tests = testGroup "DerivingDataRepr"+  [ testCase "OneHotOverlap" $ oneHotOverlapRepr @?= oneHotOverlapRepr'+  , testCase "OneHotWide"    $ oneHotWideRepr    @?= oneHotWideRepr'+  , testCase "BinaryOverlap" $ countOverlapRepr  @?= countOverlapRepr'+  , testCase "BinaryWide"    $ countWideRepr     @?= countWideRepr'+  , testCase "Packed"        $ packedRepr        @?= packedRepr'+  , testCase "PackedMaybe"   $ packedMaybeRGB    @?= packedMaybeRGB'+  ]
+ tests/Clash/Tests/DerivingDataReprTypes.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}++module Clash.Tests.DerivingDataReprTypes where++import Clash.Sized.Unsigned+import Clash.Annotations.BitRepresentation.Deriving++type SmallInt = Unsigned 2++data Train+  = Passenger+      -- Number of wagons:+      SmallInt+  | Freight+      -- Number of wagons:+      SmallInt+      -- Max weight:+      SmallInt+  | Maintenance+  | Toy+++data RGB+  = R+  | G+  | B++deriveDefaultAnnotation [t| RGB |]+deriveBitPack [t| RGB |]
+ tests/Clash/Tests/NFDataX.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE CPP            #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-}+{-# LANGUAGE MagicHash      #-}++module Clash.Tests.NFDataX where++import Test.Tasty+import Test.Tasty.HUnit++import GHC.Generics (Generic)+import Clash.XException (NFDataX(rnfX), errorX)++data Void                                  deriving (Generic, NFDataX)+data Unit    = Unit                        deriving (Generic, NFDataX)+data Wrapper = Wrapper Int                 deriving (Generic, NFDataX)+data Sum     = SumTypeA | SumTypeB         deriving (Generic, NFDataX)+data BigSum  = BS1 | BS2 | BS3 | BS4 | BS5 deriving (Generic, NFDataX)+data Product = Product Int Int             deriving (Generic, NFDataX)+data SP      = S Int Int | P Int           deriving (Generic, NFDataX)+data Rec0    = Rec0 {  }                   deriving (Generic, NFDataX)+data Rec1    = Rec1 { a :: Int }           deriving (Generic, NFDataX)+data Rec2    = Rec2 { b :: Int, c :: Int } deriving (Generic, NFDataX)++undef :: a+undef = errorX "!"+{-# NOINLINE undef #-}++tests :: TestTree+tests =+  testGroup+    "NFDataX"+    [ testGroup+        "Generic"+        [ testCase "Unit"     $ rnfX (undef :: Unit)                  @?= ()+        , testCase "Wrapper1" $ rnfX (undef :: Wrapper)               @?= ()+        , testCase "Wrapper2" $ rnfX (Wrapper undef)                  @?= ()+        , testCase "Sum"      $ rnfX (undef :: Sum)                   @?= ()+        , testCase "BigSum"   $ rnfX (undef :: BigSum)                @?= ()+        , testCase "Product1" $ rnfX (undef :: Product)               @?= ()+        , testCase "Product2" $ rnfX (Product undef undef :: Product) @?= ()+        , testCase "Product3" $ rnfX (Product 3 undef :: Product)     @?= ()+        , testCase "Product4" $ rnfX (Product undef 5 :: Product)     @?= ()+        , testCase "SP1"      $ rnfX (undef :: SP)                    @?= ()+        , testCase "SP2"      $ rnfX (S undef undef :: SP)            @?= ()+        , testCase "SP3"      $ rnfX (S 3 undef :: SP)                @?= ()+        , testCase "SP3"      $ rnfX (S undef 5 :: SP)                @?= ()+        , testCase "SP4"      $ rnfX (P undef :: SP)                  @?= ()+        , testCase "Rec0"     $ rnfX (undef :: Rec0)                  @?= ()+        , testCase "Rec1_1"   $ rnfX (undef :: Rec1)                  @?= ()+        , testCase "Rec1_2"   $ rnfX (Rec1 undef)                     @?= ()+        , testCase "Rec2_1"   $ rnfX (undef :: Rec2)                  @?= ()+        , testCase "Rec2_2"   $ rnfX (Rec2 3 undef)                   @?= ()+        , testCase "Rec2_3"   $ rnfX (Rec2 undef 5)                   @?= ()+--          Test case broken on 8.2.2:+--        , testCase "Void"     $ rnfX (undef :: Void)                  @?= ()+        ]+    , testGroup+        "Manual"+        [ testCase "List1"     $ rnfX (undef :: [Int])                @?= ()+        , testCase "List2"     $ rnfX ([undef] :: [Int])              @?= ()+        , testCase "Maybe1"    $ rnfX (undef :: Maybe Int)            @?= ()+        , testCase "Maybe2"    $ rnfX (Just undef :: Maybe Int)       @?= ()+        , testCase "Either1"   $ rnfX (undef :: Either Int Int)       @?= ()+        , testCase "Either2"   $ rnfX (Left undef :: Either Int Int)  @?= ()+        , testCase "Either3"   $ rnfX (Right undef :: Either Int Int) @?= ()+        ]+    ]+
+ tests/Clash/Tests/Signal.hs view
@@ -0,0 +1,178 @@+{-|+Copyright  :  (C) 2019, Myrtle Software Ltd+License    :  BSD2 (see the file LICENSE)+Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+-}++{-# LANGUAGE CPP                       #-}+{-# LANGUAGE RankNTypes                #-}+{-# LANGUAGE TypeApplications          #-}+{-# LANGUAGE FlexibleContexts          #-}+{-# LANGUAGE NoMonomorphismRestriction #-}++{-# OPTIONS_GHC -Wno-missing-signatures #-}++module Clash.Tests.Signal where++import           Clash.Signal++import           Data.List                      (isInfixOf)+import           Test.Tasty+import           Test.Tasty.HUnit++import qualified Language.Haskell.Interpreter   as Hint+import           Language.Haskell.Interpreter   (OptionVal((:=)))++customTypeMark :: String+customTypeMark = "You tried to apply an explicitly routed clock, reset, or enable line"++typeCheck+  :: String+  -> IO (Either Hint.InterpreterError ())+typeCheck expr =+  Hint.runInterpreter $ do+    Hint.setImports ["Clash.Prelude"]+    Hint.set [Hint.languageExtensions := [Hint.RankNTypes, Hint.TypeApplications]]+    mapM_ Hint.runStmt [test0s, test1s, test2s, test3s, test4s]+    Hint.interpret expr (Hint.as :: ())++assertCustomTypeError :: String -> String -> Assertion+assertCustomTypeError expectedErr expr = do+  result <- typeCheck expr+  case result of+    Left err ->+      if expectedErr `isInfixOf` show err then+        pure ()+      else+        assertFailure $+             "Expression failed to typecheck as expected, but did not contain "+          ++ "expected type error. Instead it contained: " ++ show err+    Right () ->+      assertFailure "Expression should have failed to typecheck, but succeeded."++main :: IO ()+main = defaultMain tests++test0s, test1s, test2s, test3s :: String+test0s = "let test0 = undefined :: Signal dom1 a -> Signal dom2 Int"+test1s = "let test1 = undefined :: Int -> Char -> Int"+test2s = "let test2 = undefined :: Signal System a -> Signal XilinxSystem Int"+test3s = "let test3 = () :: ()"+test4s = "let test4 = undefined :: ((Signal dom1 a, Signal dom2 a), Signal dom3 a)"+test5s = "let test5 = undefined :: ((Char, Signal dom1 a), Signal dom2 a)"++test0 :: forall dom1 dom2. Signal dom1 Int -> Signal dom2 Int+test0 = undefined++test1 :: Int -> Char -> Int+test1 = undefined++test2 :: Signal System a -> Signal XilinxSystem Int+test2 = undefined++test3 :: ()+test3 = ()++test4+  :: forall dom1 dom2 dom3 dom4 a+   . ((Signal dom1 a, Signal dom2 a), Signal dom3 a)+  -> Signal dom4 a+test4 = undefined++test5+  :: forall dom1 dom2 a b+   . ((b, Signal dom1 a), Signal dom2 a)+test5 = undefined++acte :: String -> Assertion+acte = assertCustomTypeError customTypeMark++tests :: TestTree+tests =+  testGroup+    "Signal"+    [ testGroup+        "Implicit"+        [ -- See: https://github.com/clash-lang/clash-compiler/pull/655+          let rst0 = fromList [True, True, False, False, True, True]+              rst1 = unsafeFromHighPolarity rst0+              reg  = register 'a' (pure 'b')+#ifdef CLASH_MULTIPLE_HIDDEN+              sig = withReset rst1 reg+#else+              sig = withReset @System rst1 reg+#endif+          in  testCase "withReset behavior" (sampleN @System 6 sig @?= "aaabaa")++#ifdef CLASH_MULTIPLE_HIDDEN+          -- See: https://github.com/clash-lang/clash-compiler/pull/669+        , testCase "test0nok_0" (acte "withReset resetGen test0")+        , testCase "test0nok_1" (acte "withReset (resetGen @System) test0")+        , testCase "test0nok_2" (acte "withReset @System (resetGen @System) test0")+        , testCase+            "test0nok_3"+            (acte+              (unwords+                [ "withReset", "@System", "(resetGen @System)"+                , "(test0 :: Signal System a -> Signal dom Int)"+                ]))++        , testCase "test0nok_4" (acte "withSpecificReset resetGen test0")+        , testCase "test0nok_5" (acte "withSpecificReset (resetGen @System) test0")++        , testCase "test1nok_0" (acte "withReset resetGen test1")+        , testCase "test1nok_1" (acte "withReset (resetGen @System) test1")+        , testCase "test1nok_2" (acte "withSpecificReset resetGen test1")+        , testCase "test1nok_3" (acte "withSpecificReset (resetGen @System) test1")++        , testCase "test2nok_0" (acte "withReset resetGen test2")+        , testCase "test2nok_1" (acte "withReset (resetGen @System) test2")+        , testCase "test2nok_2" (acte "withSpecificReset resetGen test2")++        , testCase "test3nok_0" (acte "withReset resetGen test3")+        , testCase "test3nok_1" (acte "withReset (resetGen @System) test3")+        , testCase "test3nok_2" (acte "withSpecificReset resetGen test3")+        , testCase "test3nok_3" (acte "withSpecificReset (resetGen @System) test3")++        , testCase "test4nok_0" (acte $+             "withSpecificReset resetGen (test4 :: "+          ++ "((Signal System a, Signal dom2 a), Signal dom3 a)"+          ++ "-> Signal dom4 a)" )++        , testCase "test4nok_1" (acte $+             "withSpecificReset resetGen (test4 :: "+          ++ "((Signal dom1 a, Signal System a), Signal dom3 a)"+          ++ "-> Signal dom4 a)" )++        , testCase "test4nok_2" (acte $+             "withReset resetGen (test4 :: "+          ++ "((Signal System a, Signal dom2 a), Signal dom3 a)"+          ++ "-> Signal dom4 a)" )++        , testCase "test4nok_3" (acte $+             "withReset resetGen (test4 :: "+          ++ "((Signal dom1 a, Signal System a), Signal dom3 a)"+          ++ "-> Signal dom4 a)" )++        , testCase "test5nok_0" (acte "withSpecificReset resetGen test5")+#endif+        ]+    ]++-- Tests below should survive compilation:+test0ok_0 = withReset @System (resetGen @System) (test0 @System @System)+#ifdef CLASH_MULTIPLE_HIDDEN+test0ok_1 = withReset resetGen (test0 @System @System)+test0ok_2 = withSpecificReset (resetGen @System) (test0 @System)+test0ok_3 = withSpecificReset (resetGen @System) (test0 @_ @System)++test2ok_0 = withSpecificReset (resetGen @System) test2+test2ok_1 = withSpecificReset @System resetGen test2++test4ok_0 = withReset resetGen (test4 @System @System @System @System)+test4ok_1 = withSpecificReset (resetGen @System) (test4 @System @_ @_ @_)+test4ok_2 = withSpecificReset (resetGen @System) (test4 @_ @System @_ @_)+test4ok_3 = withSpecificReset (resetGen @System) (test4 @_ @_ @System @_)++test5ok_0 = withSpecificReset (resetGen @System) (test5 @System @_)+#endif
tests/doctests.hs view
@@ -4,9 +4,9 @@ import Test.DocTest (doctest)  main :: IO ()-main = doctest (docTestOpts ++ ["-isrc","src/Clash/Prelude.hs"]) >>-       doctest (docTestOpts ++ ["src/Clash/Tutorial.hs"]) >>-       doctest (docTestOpts ++ ["src/Clash/Examples.hs"])+main = doctest (docTestOpts ++ ["-isrc","src/Clash/Prelude.hs"+                               ,"src/Clash/Tutorial.hs"+                               ,"src/Clash/Examples.hs"])  docTestOpts :: [String] docTestOpts =
+ tests/unittests.hs view
@@ -0,0 +1,21 @@+module Main where++import Test.Tasty++import qualified Clash.Tests.BitPack+import qualified Clash.Tests.BitVector+import qualified Clash.Tests.DerivingDataRepr+import qualified Clash.Tests.Signal+import qualified Clash.Tests.NFDataX++tests :: TestTree+tests = testGroup "Unittests"+  [ Clash.Tests.BitPack.tests+  , Clash.Tests.BitVector.tests+  , Clash.Tests.DerivingDataRepr.tests+  , Clash.Tests.Signal.tests+  , Clash.Tests.NFDataX.tests+  ]++main :: IO ()+main = defaultMain tests