retroclash-sim-0.1.0: src/RetroClash/Sim/IO.hs
{-# LANGUAGE RankNTypes #-}
module RetroClash.Sim.IO
( simulateIO
, simulateIO_
) where
import Clash.Prelude
import Control.Concurrent
import Control.Monad.IO.Class
import Control.Monad (void)
import Control.Arrow.Transformer.Automaton
simulateIO
:: (KnownDomain dom, MonadIO m, NFDataX i, NFDataX o)
=> (HiddenClockResetEnable dom => Signal dom i -> Signal dom o)
-> i
-> IO ((o -> m (i, a)) -> m a)
simulateIO circuit input0 = do
let Automaton step = signalAutomaton circuit
ref <- newMVar $ step input0
return $ \world -> do
(out, Automaton step) <- liftIO $ takeMVar ref
(input, result) <- world out
liftIO $ putMVar ref $ step input
return result
simulateIO_
:: (KnownDomain dom, MonadIO m, NFDataX i, NFDataX o)
=> (HiddenClockResetEnable dom => Signal dom i -> Signal dom o)
-> i
-> IO ((o -> m i) -> m ())
simulateIO_ circuit input0 = do
sim <- simulateIO circuit input0
return $ \world -> do
void $ sim $ \output -> do
input <- world output
return (input, ())