{-|
  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 GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

#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      (Signal, Domain, 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 { DSignal dom delay a -> Signal dom a
toSignal :: Signal dom a
              -- ^ Strip a 'DSignal' from its delay information.
            }
  deriving ( Int -> DSignal dom delay a -> ShowS
[DSignal dom delay a] -> ShowS
DSignal dom delay a -> String
(Int -> DSignal dom delay a -> ShowS)
-> (DSignal dom delay a -> String)
-> ([DSignal dom delay a] -> ShowS)
-> Show (DSignal dom delay a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (dom :: Domain) (delay :: Nat) a.
Show a =>
Int -> DSignal dom delay a -> ShowS
forall (dom :: Domain) (delay :: Nat) a.
Show a =>
[DSignal dom delay a] -> ShowS
forall (dom :: Domain) (delay :: Nat) a.
Show a =>
DSignal dom delay a -> String
showList :: [DSignal dom delay a] -> ShowS
$cshowList :: forall (dom :: Domain) (delay :: Nat) a.
Show a =>
[DSignal dom delay a] -> ShowS
show :: DSignal dom delay a -> String
$cshow :: forall (dom :: Domain) (delay :: Nat) a.
Show a =>
DSignal dom delay a -> String
showsPrec :: Int -> DSignal dom delay a -> ShowS
$cshowsPrec :: forall (dom :: Domain) (delay :: Nat) a.
Show a =>
Int -> DSignal dom delay a -> ShowS
Show, DSignal dom delay a
DSignal dom delay a -> Default (DSignal dom delay a)
forall a. a -> Default a
forall (dom :: Domain) (delay :: Nat) a.
Default a =>
DSignal dom delay a
def :: DSignal dom delay a
$cdef :: forall (dom :: Domain) (delay :: Nat) a.
Default a =>
DSignal dom delay a
Default, a -> DSignal dom delay b -> DSignal dom delay a
(a -> b) -> DSignal dom delay a -> DSignal dom delay b
(forall a b.
 (a -> b) -> DSignal dom delay a -> DSignal dom delay b)
-> (forall a b. a -> DSignal dom delay b -> DSignal dom delay a)
-> Functor (DSignal dom delay)
forall a b. a -> DSignal dom delay b -> DSignal dom delay a
forall a b. (a -> b) -> DSignal dom delay a -> DSignal dom delay b
forall (dom :: Domain) (delay :: Nat) a b.
a -> DSignal dom delay b -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a b.
(a -> b) -> DSignal dom delay a -> DSignal dom delay b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> DSignal dom delay b -> DSignal dom delay a
$c<$ :: forall (dom :: Domain) (delay :: Nat) a b.
a -> DSignal dom delay b -> DSignal dom delay a
fmap :: (a -> b) -> DSignal dom delay a -> DSignal dom delay b
$cfmap :: forall (dom :: Domain) (delay :: Nat) a b.
(a -> b) -> DSignal dom delay a -> DSignal dom delay b
Functor, Functor (DSignal dom delay)
a -> DSignal dom delay a
Functor (DSignal dom delay) =>
(forall a. a -> DSignal dom delay a)
-> (forall a b.
    DSignal dom delay (a -> b)
    -> DSignal dom delay a -> DSignal dom delay b)
-> (forall a b c.
    (a -> b -> c)
    -> DSignal dom delay a
    -> DSignal dom delay b
    -> DSignal dom delay c)
-> (forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b)
-> (forall a b.
    DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a)
-> Applicative (DSignal dom delay)
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
DSignal dom delay (a -> b)
-> DSignal dom delay a -> DSignal dom delay b
(a -> b -> c)
-> DSignal dom delay a
-> DSignal dom delay b
-> DSignal dom delay c
forall a. a -> DSignal dom delay a
forall a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
forall a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
forall a b.
DSignal dom delay (a -> b)
-> DSignal dom delay a -> DSignal dom delay b
forall a b c.
(a -> b -> c)
-> DSignal dom delay a
-> DSignal dom delay b
-> DSignal dom delay c
forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
forall (dom :: Domain) (delay :: Nat) a. a -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay (a -> b)
-> DSignal dom delay a -> DSignal dom delay b
forall (dom :: Domain) (delay :: Nat) a b c.
(a -> b -> c)
-> DSignal dom delay a
-> DSignal dom delay b
-> DSignal dom delay c
forall (f :: Type -> Type).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
$c<* :: forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay a
*> :: DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
$c*> :: forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay a -> DSignal dom delay b -> DSignal dom delay b
liftA2 :: (a -> b -> c)
-> DSignal dom delay a
-> DSignal dom delay b
-> DSignal dom delay c
$cliftA2 :: forall (dom :: Domain) (delay :: Nat) a b c.
(a -> b -> c)
-> DSignal dom delay a
-> DSignal dom delay b
-> DSignal dom delay c
<*> :: DSignal dom delay (a -> b)
-> DSignal dom delay a -> DSignal dom delay b
$c<*> :: forall (dom :: Domain) (delay :: Nat) a b.
DSignal dom delay (a -> b)
-> DSignal dom delay a -> DSignal dom delay b
pure :: a -> DSignal dom delay a
$cpure :: forall (dom :: Domain) (delay :: Nat) a. a -> DSignal dom delay a
$cp1Applicative :: forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
Applicative, Integer -> DSignal dom delay a
DSignal dom delay a -> DSignal dom delay a
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
(DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a
    -> DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a
    -> DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a -> DSignal dom delay a)
-> (Integer -> DSignal dom delay a)
-> Num (DSignal dom delay a)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall (dom :: Domain) (delay :: Nat) a.
Num a =>
Integer -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
fromInteger :: Integer -> DSignal dom delay a
$cfromInteger :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
Integer -> DSignal dom delay a
signum :: DSignal dom delay a -> DSignal dom delay a
$csignum :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a
abs :: DSignal dom delay a -> DSignal dom delay a
$cabs :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a
negate :: DSignal dom delay a -> DSignal dom delay a
$cnegate :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a
* :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
$c* :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
- :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
$c- :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
+ :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
$c+ :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
Num, Num (DSignal dom delay a)
Num (DSignal dom delay a) =>
(DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a)
-> (DSignal dom delay a -> DSignal dom delay a)
-> (Rational -> DSignal dom delay a)
-> Fractional (DSignal dom delay a)
Rational -> DSignal dom delay a
DSignal dom delay a -> DSignal dom delay a
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
Num (DSignal dom delay a)
forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
Rational -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
DSignal dom delay a -> DSignal dom delay a
forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
fromRational :: Rational -> DSignal dom delay a
$cfromRational :: forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
Rational -> DSignal dom delay a
recip :: DSignal dom delay a -> DSignal dom delay a
$crecip :: forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
DSignal dom delay a -> DSignal dom delay a
/ :: DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
$c/ :: forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
DSignal dom delay a -> DSignal dom delay a -> DSignal dom delay a
$cp1Fractional :: forall (dom :: Domain) (delay :: Nat) a.
Fractional a =>
Num (DSignal dom delay a)
Fractional
           , a -> DSignal dom delay a -> Bool
DSignal dom delay m -> m
DSignal dom delay a -> [a]
DSignal dom delay a -> Bool
DSignal dom delay a -> Int
DSignal dom delay a -> a
DSignal dom delay a -> a
DSignal dom delay a -> a
DSignal dom delay a -> a
(a -> m) -> DSignal dom delay a -> m
(a -> m) -> DSignal dom delay a -> m
(a -> b -> b) -> b -> DSignal dom delay a -> b
(a -> b -> b) -> b -> DSignal dom delay a -> b
(b -> a -> b) -> b -> DSignal dom delay a -> b
(b -> a -> b) -> b -> DSignal dom delay a -> b
(a -> a -> a) -> DSignal dom delay a -> a
(a -> a -> a) -> DSignal dom delay a -> a
(forall m. Monoid m => DSignal dom delay m -> m)
-> (forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m)
-> (forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m)
-> (forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b)
-> (forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b)
-> (forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b)
-> (forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b)
-> (forall a. (a -> a -> a) -> DSignal dom delay a -> a)
-> (forall a. (a -> a -> a) -> DSignal dom delay a -> a)
-> (forall a. DSignal dom delay a -> [a])
-> (forall a. DSignal dom delay a -> Bool)
-> (forall a. DSignal dom delay a -> Int)
-> (forall a. Eq a => a -> DSignal dom delay a -> Bool)
-> (forall a. Ord a => DSignal dom delay a -> a)
-> (forall a. Ord a => DSignal dom delay a -> a)
-> (forall a. Num a => DSignal dom delay a -> a)
-> (forall a. Num a => DSignal dom delay a -> a)
-> Foldable (DSignal dom delay)
forall a. Eq a => a -> DSignal dom delay a -> Bool
forall a. Num a => DSignal dom delay a -> a
forall a. Ord a => DSignal dom delay a -> a
forall m. Monoid m => DSignal dom delay m -> m
forall a. DSignal dom delay a -> Bool
forall a. DSignal dom delay a -> Int
forall a. DSignal dom delay a -> [a]
forall a. (a -> a -> a) -> DSignal dom delay a -> a
forall m a. Monoid m => (a -> m) -> DSignal dom delay a -> m
forall b a. (b -> a -> b) -> b -> DSignal dom delay a -> b
forall a b. (a -> b -> b) -> b -> DSignal dom delay a -> b
forall (dom :: Domain) (delay :: Nat) a.
Eq a =>
a -> DSignal dom delay a -> Bool
forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> a
forall (dom :: Domain) (delay :: Nat) a.
Ord a =>
DSignal dom delay a -> a
forall (dom :: Domain) (delay :: Nat) m.
Monoid m =>
DSignal dom delay m -> m
forall (dom :: Domain) (delay :: Nat) a.
DSignal dom delay a -> Bool
forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> Int
forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> [a]
forall (dom :: Domain) (delay :: Nat) a.
(a -> a -> a) -> DSignal dom delay a -> a
forall (dom :: Domain) (delay :: Nat) m a.
Monoid m =>
(a -> m) -> DSignal dom delay a -> m
forall (dom :: Domain) (delay :: Nat) b a.
(b -> a -> b) -> b -> DSignal dom delay a -> b
forall (dom :: Domain) (delay :: Nat) a b.
(a -> b -> b) -> b -> DSignal dom delay a -> b
forall (t :: Type -> Type).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: DSignal dom delay a -> a
$cproduct :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> a
sum :: DSignal dom delay a -> a
$csum :: forall (dom :: Domain) (delay :: Nat) a.
Num a =>
DSignal dom delay a -> a
minimum :: DSignal dom delay a -> a
$cminimum :: forall (dom :: Domain) (delay :: Nat) a.
Ord a =>
DSignal dom delay a -> a
maximum :: DSignal dom delay a -> a
$cmaximum :: forall (dom :: Domain) (delay :: Nat) a.
Ord a =>
DSignal dom delay a -> a
elem :: a -> DSignal dom delay a -> Bool
$celem :: forall (dom :: Domain) (delay :: Nat) a.
Eq a =>
a -> DSignal dom delay a -> Bool
length :: DSignal dom delay a -> Int
$clength :: forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> Int
null :: DSignal dom delay a -> Bool
$cnull :: forall (dom :: Domain) (delay :: Nat) a.
DSignal dom delay a -> Bool
toList :: DSignal dom delay a -> [a]
$ctoList :: forall (dom :: Domain) (delay :: Nat) a. DSignal dom delay a -> [a]
foldl1 :: (a -> a -> a) -> DSignal dom delay a -> a
$cfoldl1 :: forall (dom :: Domain) (delay :: Nat) a.
(a -> a -> a) -> DSignal dom delay a -> a
foldr1 :: (a -> a -> a) -> DSignal dom delay a -> a
$cfoldr1 :: forall (dom :: Domain) (delay :: Nat) a.
(a -> a -> a) -> DSignal dom delay a -> a
foldl' :: (b -> a -> b) -> b -> DSignal dom delay a -> b
$cfoldl' :: forall (dom :: Domain) (delay :: Nat) b a.
(b -> a -> b) -> b -> DSignal dom delay a -> b
foldl :: (b -> a -> b) -> b -> DSignal dom delay a -> b
$cfoldl :: forall (dom :: Domain) (delay :: Nat) b a.
(b -> a -> b) -> b -> DSignal dom delay a -> b
foldr' :: (a -> b -> b) -> b -> DSignal dom delay a -> b
$cfoldr' :: forall (dom :: Domain) (delay :: Nat) a b.
(a -> b -> b) -> b -> DSignal dom delay a -> b
foldr :: (a -> b -> b) -> b -> DSignal dom delay a -> b
$cfoldr :: forall (dom :: Domain) (delay :: Nat) a b.
(a -> b -> b) -> b -> DSignal dom delay a -> b
foldMap' :: (a -> m) -> DSignal dom delay a -> m
$cfoldMap' :: forall (dom :: Domain) (delay :: Nat) m a.
Monoid m =>
(a -> m) -> DSignal dom delay a -> m
foldMap :: (a -> m) -> DSignal dom delay a -> m
$cfoldMap :: forall (dom :: Domain) (delay :: Nat) m a.
Monoid m =>
(a -> m) -> DSignal dom delay a -> m
fold :: DSignal dom delay m -> m
$cfold :: forall (dom :: Domain) (delay :: Nat) m.
Monoid m =>
DSignal dom delay m -> m
Foldable, Functor (DSignal dom delay)
Foldable (DSignal dom delay)
(Functor (DSignal dom delay), Foldable (DSignal dom delay)) =>
(forall (f :: Type -> Type) a b.
 Applicative f =>
 (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    DSignal dom delay (f a) -> f (DSignal dom delay a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b))
-> (forall (m :: Type -> Type) a.
    Monad m =>
    DSignal dom delay (m a) -> m (DSignal dom delay a))
-> Traversable (DSignal dom delay)
(a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
forall (dom :: Domain) (delay :: Nat). Foldable (DSignal dom delay)
forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a.
Monad m =>
DSignal dom delay (m a) -> m (DSignal dom delay a)
forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a.
Applicative f =>
DSignal dom delay (f a) -> f (DSignal dom delay a)
forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
forall (t :: Type -> Type).
(Functor t, Foldable t) =>
(forall (f :: Type -> Type) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    t (f a) -> f (t a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: Type -> Type) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: Type -> Type) a.
Monad m =>
DSignal dom delay (m a) -> m (DSignal dom delay a)
forall (f :: Type -> Type) a.
Applicative f =>
DSignal dom delay (f a) -> f (DSignal dom delay a)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
sequence :: DSignal dom delay (m a) -> m (DSignal dom delay a)
$csequence :: forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a.
Monad m =>
DSignal dom delay (m a) -> m (DSignal dom delay a)
mapM :: (a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
$cmapM :: forall (dom :: Domain) (delay :: Nat) (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> DSignal dom delay a -> m (DSignal dom delay b)
sequenceA :: DSignal dom delay (f a) -> f (DSignal dom delay a)
$csequenceA :: forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a.
Applicative f =>
DSignal dom delay (f a) -> f (DSignal dom delay a)
traverse :: (a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
$ctraverse :: forall (dom :: Domain) (delay :: Nat) (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> DSignal dom delay a -> f (DSignal dom delay b)
$cp2Traversable :: forall (dom :: Domain) (delay :: Nat). Foldable (DSignal dom delay)
$cp1Traversable :: forall (dom :: Domain) (delay :: Nat). Functor (DSignal dom delay)
Traversable, Gen (DSignal dom delay a)
Gen (DSignal dom delay a)
-> (DSignal dom delay a -> [DSignal dom delay a])
-> Arbitrary (DSignal dom delay a)
DSignal dom delay a -> [DSignal dom delay a]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
forall (dom :: Domain) (delay :: Nat) a.
Arbitrary a =>
Gen (DSignal dom delay a)
forall (dom :: Domain) (delay :: Nat) a.
Arbitrary a =>
DSignal dom delay a -> [DSignal dom delay a]
shrink :: DSignal dom delay a -> [DSignal dom delay a]
$cshrink :: forall (dom :: Domain) (delay :: Nat) a.
Arbitrary a =>
DSignal dom delay a -> [DSignal dom delay a]
arbitrary :: Gen (DSignal dom delay a)
$carbitrary :: forall (dom :: Domain) (delay :: Nat) a.
Arbitrary a =>
Gen (DSignal dom delay a)
Arbitrary, DSignal dom delay a -> Gen b -> Gen b
(forall b. DSignal dom delay a -> Gen b -> Gen b)
-> CoArbitrary (DSignal dom delay a)
forall b. DSignal dom delay a -> Gen b -> Gen b
forall a. (forall b. a -> Gen b -> Gen b) -> CoArbitrary a
forall (dom :: Domain) (delay :: Nat) a b.
CoArbitrary a =>
DSignal dom delay a -> Gen b -> Gen b
coarbitrary :: DSignal dom delay a -> Gen b -> Gen b
$ccoarbitrary :: forall (dom :: Domain) (delay :: Nat) a b.
CoArbitrary a =>
DSignal dom delay a -> Gen b -> Gen b
CoArbitrary, DSignal dom delay a -> Q Exp
(DSignal dom delay a -> Q Exp) -> Lift (DSignal dom delay a)
forall t. (t -> Q Exp) -> Lift t
forall (dom :: Domain) (delay :: Nat) a.
Lift a =>
DSignal dom delay a -> Q Exp
lift :: DSignal dom delay a -> Q Exp
$clift :: forall (dom :: Domain) (delay :: Nat) a.
Lift a =>
DSignal dom delay a -> Q Exp
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 :: [a] -> DSignal dom 0 a
dfromList = Signal Any a -> DSignal dom 0 a
forall a b. Coercible a b => a -> b
coerce (Signal Any a -> DSignal dom 0 a)
-> ([a] -> Signal Any a) -> [a] -> DSignal dom 0 a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Signal Any a
forall a (dom :: Domain). NFDataX a => [a] -> Signal dom a
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 :: [a] -> DSignal dom 0 a
dfromList_lazy = Signal Any a -> DSignal dom 0 a
forall a b. Coercible a b => a -> b
coerce (Signal Any a -> DSignal dom 0 a)
-> ([a] -> Signal Any a) -> [a] -> DSignal dom 0 a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Signal Any a
forall a (dom :: Domain). [a] -> Signal dom a
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 :: (DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a))
-> DSignal dom n a
feedback f :: DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)
f = let (o :: DSignal dom n a
o,r :: DSignal dom ((n + m) + 1) a
r) = DSignal dom n a -> (DSignal dom n a, DSignal dom ((n + m) + 1) a)
f (DSignal dom ((n + m) + 1) a -> DSignal dom n a
forall a b. Coercible a b => a -> b
coerce DSignal dom ((n + m) + 1) a
r) in DSignal dom n a
o

-- | 'Signal's are not delayed
--
-- > sample s == dsample (fromSignal s)
fromSignal :: Signal dom a -> DSignal dom 0 a
fromSignal :: Signal dom a -> DSignal dom 0 a
fromSignal = Signal dom a -> DSignal dom 0 a
forall a b. Coercible a b => a -> b
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 :: Signal dom a -> DSignal dom n a
unsafeFromSignal = Signal dom a -> DSignal dom n a
forall (dom :: Domain) (delay :: Nat) a.
Signal dom a -> DSignal dom delay a
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 :: SNat d -> DSignal dom (n + d) a -> DSignal dom n a
antiDelay _ = DSignal dom (n + d) a -> DSignal dom n a
forall a b. Coercible a b => a -> b
coerce