From ae93aee6919f9686d837c4f0a0ce92a90baf13bd Mon Sep 17 00:00:00 2001 From: Rowan Goemans Date: Thu, 14 Mar 2024 17:26:24 +0100 Subject: [PATCH] Df: `registerBwd` now places only a single register on the data path --- src/Protocols/Df.hs | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/Protocols/Df.hs b/src/Protocols/Df.hs index 5b6f222d..9733c61c 100644 --- a/src/Protocols/Df.hs +++ b/src/Protocols/Df.hs @@ -59,6 +59,9 @@ module Protocols.Df , forceResetSanity , dataToMaybe , maybeToData + , hasData + , fromData + , toData ) where -- base @@ -152,6 +155,21 @@ maybeToData :: Maybe a -> Data a maybeToData Nothing = NoData maybeToData (Just a) = Data a +-- | True if `Data` contains a value +hasData :: Data a -> Bool +hasData NoData = False +hasData (Data _) = True + +-- | Extract value from `Data`, Bottom on `NoData` +fromData :: (HasCallStack, C.NFDataX a) => Data a -> a +fromData NoData = deepErrorX "fromData: NoData" +fromData (Data a) = a + +-- | Construct a `Data` if bool is True, `NoData` otherwise +toData :: Bool -> a -> Data a +toData False _ = NoData +toData True a = Data a + instance (C.KnownDomain dom, C.NFDataX a, C.ShowX a, Show a) => Simulate (Df dom a) where type SimulateFwdType (Df dom a) = [Data a] type SimulateBwdType (Df dom a) = [Ack] @@ -632,7 +650,7 @@ roundrobinCollect Parallel | Maybe.isJust (dataToMaybe dat) = Just (i, dat) | otherwise = Nothing --- | Place register on /forward/ part of a circuit. +-- | Place register on /forward/ part of a circuit. This adds combinational delay on the /backward/ path registerFwd :: forall dom a . (C.NFDataX a, C.HiddenClockResetEnable dom) => @@ -645,21 +663,21 @@ registerFwd oAck = Maybe.isNothing (dataToMaybe s0) || iAck s1 = if oAck then iDat else s0 --- | Place register on /backward/ part of a circuit. This is implemented using a --- in-logic two-element shift register. +-- | Place register on /backward/ part of a circuit. This adds combinational delay on the /forward/ path registerBwd :: forall dom a . (C.NFDataX a, C.HiddenClockResetEnable dom) => Circuit (Df dom a) (Df dom a) registerBwd - = forceResetSanity |> Circuit (C.mealyB go (NoData, NoData)) + = forceResetSanity |> Circuit go where - go (ra0, rb) (iDat, Ack iAck) = - (s, (Ack oAck, rb)) - where - oAck = Maybe.isNothing (dataToMaybe ra0) - ra1 = if oAck then iDat else ra0 - s = if Maybe.isNothing (dataToMaybe rb) || iAck then (NoData, ra1) else (ra1, rb) + go (iDat, iAck) = (Ack <$> oAck, oDat) + where + oAck = regEn True vldOut (coerce <$> iAck) + vldOut = (hasData <$> iDat) .||. (fmap not oAck) + iDatX0 = fromDataX <$> iDat + iDatX1 = regEn (errorX "registerBwd") oAck iDatX0 + oDat = toData <$> vldOut <*> (C.mux oAck iDatX0 iDatX1) -- | A fifo buffer with user-provided depth. Uses blockram to store data. Can -- handle simultaneous write and read (full throughput rate).