module Lava.Combinational where
import Lava.Ref
import Lava.Generic
import Lava.Signal
import Lava.Netlist
import Lava.Sequent
import Lava.Error
import Lava.MyST
( ST
, STRef
, newSTRef
, readSTRef
, writeSTRef
, runST
)
simulate :: Generic b => (a -> b) -> a -> b
simulate :: (a -> b) -> a -> b
simulate circ :: a -> b
circ inp :: a
inp = (forall s. ST s b) -> b
forall a. (forall s. ST s a) -> a
runST (
do Struct (STRef s (S Symbol))
sr <- ST s (STRef s (S Symbol))
-> (STRef s (S Symbol) -> S (STRef s (S Symbol)) -> ST s ())
-> Struct Symbol
-> ST s (Struct (STRef s (S Symbol)))
forall (f :: * -> *) s v.
Sequent f =>
ST s v -> (v -> S v -> ST s ()) -> f Symbol -> ST s (f v)
netlistST ST s (STRef s (S Symbol))
forall s a. ST s (STRef s a)
new STRef s (S Symbol) -> S (STRef s (S Symbol)) -> ST s ()
forall s a. STRef s (S a) -> S (STRef s (S a)) -> ST s ()
define (b -> Struct Symbol
forall a. Generic a => a -> Struct Symbol
struct (a -> b
circ a
inp))
Struct Symbol
sa <- (STRef s (S Symbol) -> ST s Symbol)
-> Struct (STRef s (S Symbol)) -> ST s (Struct Symbol)
forall (m :: * -> *) (s :: * -> *) a b.
(Monad m, Sequent s) =>
(a -> m b) -> s a -> m (s b)
mmap ((S Symbol -> Symbol) -> ST s (S Symbol) -> ST s Symbol
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap S Symbol -> Symbol
symbol (ST s (S Symbol) -> ST s Symbol)
-> (STRef s (S Symbol) -> ST s (S Symbol))
-> STRef s (S Symbol)
-> ST s Symbol
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STRef s (S Symbol) -> ST s (S Symbol)
forall s a. STRef s a -> ST s a
readSTRef) Struct (STRef s (S Symbol))
sr
let res :: b
res = Struct Symbol -> b
forall a. Generic a => Struct Symbol -> a
construct Struct Symbol
sa
b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return b
res
)
where
new :: ST s (STRef s a)
new =
a -> ST s (STRef s a)
forall a s. a -> ST s (STRef s a)
newSTRef (Error -> a
forall a. Error -> a
wrong Error
Lava.Error.CombinationalLoop)
define :: STRef s (S a) -> S (STRef s (S a)) -> ST s ()
define r :: STRef s (S a)
r s :: S (STRef s (S a))
s =
do S (S a)
s' <- (STRef s (S a) -> ST s (S a))
-> S (STRef s (S a)) -> ST s (S (S a))
forall (m :: * -> *) (s :: * -> *) a b.
(Monad m, Sequent s) =>
(a -> m b) -> s a -> m (s b)
mmap STRef s (S a) -> ST s (S a)
forall s a. STRef s a -> ST s a
readSTRef S (STRef s (S a))
s
STRef s (S a) -> S a -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (S a)
r (S (S a) -> S a
forall a. S (S a) -> S a
eval S (S a)
s')