module Language.KansasLava.Protocols.ReadyBox where
import Language.KansasLava.Rep
import Language.KansasLava.Signal
import Language.KansasLava.Types
import Language.KansasLava.Protocols.Enabled
import Language.KansasLava.Protocols.Types
import Language.KansasLava.Protocols.Patch
import Language.KansasLava.Probes
import Language.KansasLava.Utils
toReadyBox :: (Rep a, Clock c, sig ~ Signal c)
=> Patch [Maybe a] (sig (Enabled a))
() (sig Ready)
toReadyBox = toReadyBox' []
toReadyBox' :: (Rep a, Clock c, sig ~ Signal c)
=> [Int]
-> Patch [Maybe a] (sig (Enabled a))
() (sig Ready)
toReadyBox' pauses ~(ys,full) = ((),toS (fn ys (fromS full) pauses))
where
fn xs fs ps =
case fs of
(Nothing:_) -> error "toReadyBox: bad protocol state (1)"
(Just (Ready True) : fs') ->
case (xs,ps) of
(x:xs',0:ps') -> x : fn xs' fs' ps'
(Nothing:xs',p:ps') -> Nothing : fn xs' fs' (pred p : ps')
(_:_,p:ps') -> Nothing : fn xs fs' (pred p : ps')
(_:_,[]) -> fn xs fs (repeat 0)
(_,_) -> Nothing : fn xs fs' ps
(Just (Ready False) : fs') -> Nothing : fn xs fs' ps
[] -> error "toReadyBox: Ready seq should never end"
fromReadyBox :: forall a c sig . (Rep a, Clock c, sig ~ Signal c)
=> Patch (sig (Enabled a)) [Maybe a]
(sig Ready) ()
fromReadyBox = fromReadyBox' (repeat 0)
fromReadyBox' :: forall a c sig . (Rep a, Clock c, sig ~ Signal c)
=> [Int]
-> Patch (sig (Enabled a)) [Maybe a]
(sig Ready) ()
fromReadyBox' ps ~(inp,_) = (toS (map fst internal), map snd internal)
where
internal = fn (fromS inp) ps
fn :: [Maybe (Enabled a)] -> [Int] -> [(Ready,Maybe a)]
fn xs (0:ps') = (Ready True,v) : rest
where
(v,rest) = case xs of
(Nothing:_) -> error "found an unknown value in ReadyBox input"
(Just Nothing:xs') -> (Nothing,fn xs' (0:ps'))
(Just v':xs') -> (v',fn xs' ps')
[] -> error "fromReadyBox: Ready sequences should never end"
fn xs (p:ps') = (Ready False,Nothing) : fn (Prelude.tail xs) (pred p:ps')
fn xs [] = fn xs (repeat 0)
shallowReadyBoxBridge :: forall sig c a . (Rep a, Clock c, sig ~ Signal c, Show a)
=> ([Int],[Int])
-> Patch (sig (Enabled a)) (sig (Enabled a))
(sig Ready) (sig Ready)
shallowReadyBoxBridge (lhsF,rhsF) = patch
where
patch = fromReadyBox' lhsF $$ toReadyBox' rhsF
probeReadyBoxP :: forall sig a c . ( Rep a, Clock c, sig ~ Signal c)
=> String
-> Patch (sig (Enabled a)) (sig (Enabled a))
(sig Ready) (sig Ready)
probeReadyBoxP probeName ~(inp, ready_in) = (ready_out, out)
where
(out, _) = unpack probed
ready_out = ready_in
probed :: sig (Enabled a, Ready)
probed = probeS probeName $ pack (inp, ready_in)
runReadyBoxP :: forall sig c a b . (c ~ CLK, sig ~ Signal c, Rep a, Rep b)
=> Patch (sig (Enabled a)) (sig (Enabled b))
(sig Ready) (sig Ready)
-> [a] -> [b]
runReadyBoxP p as = [ b | Just b <- bs' ]
where
as' = map Just as
bs' = runP (outputP as' $$ toReadyBox $$ globalClockP $$ p $$ fromReadyBox)
sinkReadyP :: forall a c sig . (Rep a, Clock c, sig ~ Signal c)
=> Patch (sig (Enabled a)) ()
(sig Ready) ()
sinkReadyP ~(_, ()) = (toReady ready, ())
where
ready = high
alwaysReadyP :: forall a c sig . ( Rep a, Clock c, sig ~ Signal c)
=> a
-> Patch () (sig (Enabled a))
() (sig Ready)
alwaysReadyP baseVal ~((), ready_in) = ((), out)
where
out = packEnabled (fromReady ready_in) (pureS baseVal)
neverReadyP :: forall a c sig . (Rep a, Clock c, sig ~ Signal c)
=> Patch () (sig (Enabled a))
() (sig Ready)
neverReadyP (_,_) = ((),disabledS)