{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
module Clash.Explicit.DDR
( ddrIn
, ddrOut
, ddrIn#
, ddrOut#
)
where
import GHC.Stack (HasCallStack, withFrozenCallStack)
import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Explicit.Prelude
import Clash.Signal.Internal
ddrIn
:: ( HasCallStack
, NFDataX a
, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
, KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
=> Clock slow
-> Reset slow
-> Enable slow
-> (a, a, a)
-> Signal fast a
-> Signal slow (a, a)
ddrIn :: Clock slow
-> Reset slow
-> Enable slow
-> (a, a, a)
-> Signal fast a
-> Signal slow (a, a)
ddrIn Clock slow
clk Reset slow
rst Enable slow
en (a
i0,a
i1,a
i2) =
(HasCallStack => Signal fast a -> Signal slow (a, a))
-> Signal fast a -> Signal slow (a, a)
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Signal fast a -> Signal slow (a, a))
-> Signal fast a -> Signal slow (a, a))
-> (HasCallStack => Signal fast a -> Signal slow (a, a))
-> Signal fast a
-> Signal slow (a, a)
forall a b. (a -> b) -> a -> b
$ Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
forall a (slow :: Domain) (fast :: Domain) (fPeriod :: Nat)
(polarity :: ResetPolarity) (edge :: ActiveEdge)
(reset :: ResetKind) (init :: InitBehavior).
(HasCallStack, NFDataX a,
KnownConfiguration
fast ('DomainConfiguration fast fPeriod edge reset init polarity),
KnownConfiguration
slow
('DomainConfiguration
slow (2 * fPeriod) edge reset init polarity)) =>
Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
ddrIn# Clock slow
clk Reset slow
rst Enable slow
en a
i0 a
i1 a
i2
ddrIn#
:: forall a slow fast fPeriod polarity edge reset init
. ( HasCallStack
, NFDataX a
, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
, KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
=> Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a,a)
ddrIn# :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
ddrIn# (Clock SSymbol slow
_) (Reset slow -> Signal slow Bool
forall (dom :: Domain).
KnownDomain dom =>
Reset dom -> Signal dom Bool
unsafeToHighPolarity -> Signal slow Bool
hRst) (Enable slow -> Signal slow Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable -> Signal slow Bool
ena) a
i0 a
i1 a
i2 =
case forall (dom :: Domain) (sync :: ResetKind).
(KnownDomain dom, DomainResetKind dom ~ sync) =>
SResetKind sync
forall (sync :: ResetKind).
(KnownDomain fast, DomainResetKind fast ~ sync) =>
SResetKind sync
resetKind @fast of
SResetKind reset
SAsynchronous ->
(a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync
( String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 0 undefined"
, String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 1 undefined"
, String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 2 undefined" )
Signal slow Bool
hRst
Signal slow Bool
ena
SResetKind reset
SSynchronous ->
(a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync
( String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 0 undefined"
, String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 1 undefined"
, String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 2 undefined" )
Signal slow Bool
hRst
Signal slow Bool
ena
where
goSync
:: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a,a)
goSync :: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0,a
o1,a
o2) rt :: Signal slow Bool
rt@(~(Bool
r :- Signal slow Bool
rs)) ~(Bool
e :- Signal slow Bool
es) as :: Signal fast a
as@(~(a
x0 :- a
x1 :- Signal fast a
xs)) =
let (a
o0',a
o1',a
o2') = if Bool
r then (a
i0,a
i1,a
i2) else (a
o2,a
x0,a
x1)
in a
o0 a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` a
o1 a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` (a
o0,a
o1)
(a, a) -> Signal slow (a, a) -> Signal slow (a, a)
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- (Signal slow Bool
rt Signal slow Bool -> Signal slow (a, a) -> Signal slow (a, a)
`seq` Signal fast a
as Signal fast a -> Signal slow (a, a) -> Signal slow (a, a)
`seq` if Bool
e then (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0',a
o1',a
o2') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs
else (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0 ,a
o1 ,a
o2) Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs)
goAsync
:: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync :: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o0,a
o1,a
o2) ~(Bool
r :- Signal slow Bool
rs) ~(Bool
e :- Signal slow Bool
es) as :: Signal fast a
as@(~(a
x0 :- a
x1 :- Signal fast a
xs)) =
let (a
o0',a
o1',a
o2',a
o3',a
o4') = if Bool
r then (a
i0,a
i1,a
i0,a
i1,a
i2) else (a
o0,a
o1,a
o2,a
x0,a
x1)
in a
o0' a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` a
o1' a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` (a
o0',a
o1')
(a, a) -> Signal slow (a, a) -> Signal slow (a, a)
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- (Signal fast a
as Signal fast a -> Signal slow (a, a) -> Signal slow (a, a)
`seq` if Bool
e then (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o2',a
o3',a
o4') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs
else (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o0',a
o1',a
o2') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs)
{-# NOINLINE ddrIn# #-}
{-# ANN ddrIn# hasBlackBox #-}
ddrOut
:: ( HasCallStack
, NFDataX a
, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
, KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
=> Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow (a, a)
-> Signal fast a
ddrOut :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow (a, a)
-> Signal fast a
ddrOut Clock slow
clk Reset slow
rst Enable slow
en a
i0 =
(Signal slow a -> Signal slow a -> Signal fast a)
-> (Signal slow a, Signal slow a) -> Signal fast a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((HasCallStack => Signal slow a -> Signal slow a -> Signal fast a)
-> Signal slow a -> Signal slow a -> Signal fast a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Signal slow a -> Signal slow a -> Signal fast a)
-> Signal slow a -> Signal slow a -> Signal fast a)
-> (HasCallStack =>
Signal slow a -> Signal slow a -> Signal fast a)
-> Signal slow a
-> Signal slow a
-> Signal fast a
forall a b. (a -> b) -> a -> b
$ Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
forall a (fast :: Domain) (fPeriod :: Nat) (edge :: ActiveEdge)
(reset :: ResetKind) (init :: InitBehavior)
(polarity :: ResetPolarity) (slow :: Domain).
(HasCallStack, NFDataX a,
KnownConfiguration
fast ('DomainConfiguration fast fPeriod edge reset init polarity),
KnownConfiguration
slow
('DomainConfiguration
slow (2 * fPeriod) edge reset init polarity)) =>
Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
ddrOut# Clock slow
clk Reset slow
rst Enable slow
en a
i0) ((Signal slow a, Signal slow a) -> Signal fast a)
-> (Signal slow (a, a) -> (Signal slow a, Signal slow a))
-> Signal slow (a, a)
-> Signal fast a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal slow (a, a) -> (Signal slow a, Signal slow a)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle
ddrOut#
:: ( HasCallStack
, NFDataX a
, KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
, KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
=> Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
ddrOut# :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
ddrOut# Clock slow
clk Reset slow
rst Enable slow
en a
i0 Signal slow a
xs Signal slow a
ys =
let (a
_ :- Signal fast a
out) = Signal slow a -> Signal slow a -> Signal fast a
forall (dom :: Domain) a (dom :: Domain) (dom :: Domain).
Signal dom a -> Signal dom a -> Signal dom a
zipSig Signal slow a
xs' Signal slow a
ys' in Signal fast a
out
where
xs' :: Signal slow a
xs' = Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> Signal slow a
-> Signal slow a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
register# Clock slow
clk Reset slow
rst Enable slow
en (String -> a
forall a. HasCallStack => String -> a
error String
"ddrOut: unreachable error") a
i0 Signal slow a
xs
ys' :: Signal slow a
ys' = Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> Signal slow a
-> Signal slow a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
register# Clock slow
clk Reset slow
rst Enable slow
en (String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrOut: initial value undefined") a
i0 Signal slow a
ys
zipSig :: Signal dom a -> Signal dom a -> Signal dom a
zipSig (a
a :- Signal dom a
as) (a
b :- Signal dom a
bs) = a
a a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- a
b a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom a -> Signal dom a -> Signal dom a
zipSig Signal dom a
as Signal dom a
bs
{-# NOINLINE ddrOut# #-}
{-# ANN ddrOut# hasBlackBox #-}