{-# LANGUAGE NoGeneralizedNewtypeDeriving #-}
{-# LANGUAGE Safe #-}
module Clash.Explicit.Mealy
(
mealy
, mealyS
, mealyB
, mealySB
)
where
import Clash.Explicit.Signal
(KnownDomain, Bundle (..), Clock, Reset, Signal, Enable, register)
import Clash.XException (NFDataX)
import Control.Monad.State.Strict
(State, runState)
mealy
:: ( KnownDomain dom
, NFDataX s )
=> Clock dom
-> Reset dom
-> Enable dom
-> (s -> i -> (s,o))
-> s
-> (Signal dom i -> Signal dom o)
mealy :: forall (dom :: Domain) s i o.
(KnownDomain dom, NFDataX s) =>
Clock dom
-> Reset dom
-> Enable dom
-> (s -> i -> (s, o))
-> s
-> Signal dom i
-> Signal dom o
mealy Clock dom
clk Reset dom
rst Enable dom
en s -> i -> (s, o)
f s
iS =
\Signal dom i
i -> let (Signal dom s
s',Signal dom o
o) = Signal dom (s, o) -> Unbundled dom (s, o)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
forall (dom :: Domain). Signal dom (s, o) -> Unbundled dom (s, o)
unbundle (Signal dom (s, o) -> Unbundled dom (s, o))
-> Signal dom (s, o) -> Unbundled dom (s, o)
forall a b. (a -> b) -> a -> b
$ s -> i -> (s, o)
f (s -> i -> (s, o)) -> Signal dom s -> Signal dom (i -> (s, o))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom s
s Signal dom (i -> (s, o)) -> Signal dom i -> Signal dom (s, o)
forall a b. Signal dom (a -> b) -> Signal dom a -> Signal dom b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Signal dom i
i
s :: Signal dom s
s = Clock dom
-> Reset dom -> Enable dom -> s -> Signal dom s -> Signal dom s
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en s
iS Signal dom s
s'
in Signal dom o
o
{-# INLINABLE mealy #-}
mealyS
:: ( KnownDomain dom
, NFDataX s )
=> Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> (Signal dom i -> Signal dom o)
mealyS :: forall (dom :: Domain) s i o.
(KnownDomain dom, NFDataX s) =>
Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> Signal dom i
-> Signal dom o
mealyS Clock dom
clk Reset dom
rst Enable dom
en i -> State s o
f s
iS =
\Signal dom i
i -> let (Signal dom o
o,Signal dom s
s') = Signal dom (o, s) -> Unbundled dom (o, s)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
forall (dom :: Domain). Signal dom (o, s) -> Unbundled dom (o, s)
unbundle (Signal dom (o, s) -> Unbundled dom (o, s))
-> Signal dom (o, s) -> Unbundled dom (o, s)
forall a b. (a -> b) -> a -> b
$ (State s o -> s -> (o, s)
forall s a. State s a -> s -> (a, s)
runState (State s o -> s -> (o, s)) -> (i -> State s o) -> i -> s -> (o, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> State s o
f) (i -> s -> (o, s)) -> Signal dom i -> Signal dom (s -> (o, s))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom i
i Signal dom (s -> (o, s)) -> Signal dom s -> Signal dom (o, s)
forall a b. Signal dom (a -> b) -> Signal dom a -> Signal dom b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Signal dom s
s
s :: Signal dom s
s = Clock dom
-> Reset dom -> Enable dom -> s -> Signal dom s -> Signal dom s
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en s
iS Signal dom s
s'
in Signal dom o
o
{-# INLINABLE mealyS #-}
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)
mealyB :: forall (dom :: Domain) s i o.
(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
mealyB Clock dom
clk Reset dom
rst Enable dom
en s -> i -> (s, o)
f s
iS Unbundled dom i
i = Signal dom o -> Unbundled dom o
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
forall (dom :: Domain). Signal dom o -> Unbundled dom o
unbundle (Clock dom
-> Reset dom
-> Enable dom
-> (s -> i -> (s, o))
-> s
-> Signal dom i
-> Signal dom o
forall (dom :: Domain) s i o.
(KnownDomain dom, NFDataX s) =>
Clock dom
-> Reset dom
-> Enable dom
-> (s -> i -> (s, o))
-> s
-> Signal dom i
-> Signal dom o
mealy Clock dom
clk Reset dom
rst Enable dom
en s -> i -> (s, o)
f s
iS (Unbundled dom i -> Signal dom i
forall a (dom :: Domain).
Bundle a =>
Unbundled dom a -> Signal dom a
forall (dom :: Domain). Unbundled dom i -> Signal dom i
bundle Unbundled dom i
i))
{-# INLINE mealyB #-}
mealySB
:: ( KnownDomain dom
, NFDataX s
, Bundle i
, Bundle o )
=> Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> (Unbundled dom i -> Unbundled dom o)
mealySB :: forall (dom :: Domain) s i o.
(KnownDomain dom, NFDataX s, Bundle i, Bundle o) =>
Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> Unbundled dom i
-> Unbundled dom o
mealySB Clock dom
clk Reset dom
rst Enable dom
en i -> State s o
f s
iS Unbundled dom i
i = Signal dom o -> Unbundled dom o
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
forall (dom :: Domain). Signal dom o -> Unbundled dom o
unbundle (Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> Signal dom i
-> Signal dom o
forall (dom :: Domain) s i o.
(KnownDomain dom, NFDataX s) =>
Clock dom
-> Reset dom
-> Enable dom
-> (i -> State s o)
-> s
-> Signal dom i
-> Signal dom o
mealyS Clock dom
clk Reset dom
rst Enable dom
en i -> State s o
f s
iS (Unbundled dom i -> Signal dom i
forall a (dom :: Domain).
Bundle a =>
Unbundled dom a -> Signal dom a
forall (dom :: Domain). Unbundled dom i -> Signal dom i
bundle Unbundled dom i
i))
{-# INLINE mealySB #-}