{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_HADDOCK hide #-}
module Protocols.PacketStream.AsyncFifo (asyncFifoC) where
import Data.Maybe.Extra (toMaybe)
import Clash.Explicit.Prelude (asyncFIFOSynchronizer)
import Clash.Prelude
import Protocols
import Protocols.PacketStream.Base
asyncFifoC ::
forall
(wDom :: Domain)
(rDom :: Domain)
(depth :: Nat)
(dataWidth :: Nat)
(meta :: Type).
(KnownDomain wDom) =>
(KnownDomain rDom) =>
(KnownNat depth) =>
(KnownNat dataWidth) =>
(2 <= depth) =>
(1 <= dataWidth) =>
(NFDataX meta) =>
SNat depth ->
Clock wDom ->
Reset wDom ->
Enable wDom ->
Clock rDom ->
Reset rDom ->
Enable rDom ->
Circuit (PacketStream wDom dataWidth meta) (PacketStream rDom dataWidth meta)
asyncFifoC depth wClk wRst wEn rClk rRst rEn =
exposeClockResetEnable forceResetSanity wClk wRst wEn |> fromSignals ckt
where
ckt (fwdIn, bwdIn) = (bwdOut, fwdOut)
where
(element, isEmpty, isFull) = asyncFIFOSynchronizer depth wClk rClk wRst rRst wEn rEn readReq fwdIn
notEmpty = not <$> isEmpty
fwdOut = toMaybe <$> notEmpty <*> element
bwdOut = PacketStreamS2M . not <$> isFull
readReq = notEmpty .&&. _ready <$> bwdIn