Skip to content

Commit

Permalink
Implemented scatterUnitWB and gatherUnitWB
Browse files Browse the repository at this point in the history
  • Loading branch information
lmbollen committed Mar 30, 2022
1 parent fe7f3e8 commit c107ed3
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 3 deletions.
106 changes: 103 additions & 3 deletions bittide/src/Bittide/ScatterGather.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ Copyright: Copyright © 2022, Google LLC
License: Apache-2.0
Maintainer: [email protected]
|-}
module Bittide.ScatterGather(scatterEngine, gatherEngine, scatterGatherEngine) where
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
module Bittide.ScatterGather(scatterEngine, gatherEngine, scatterGatherEngine, scatterUnitWB, gatherUnitWB) where

import Clash.Prelude

import Bittide.Calendar
import Bittide.DoubleBufferedRAM ( doubleBufferedRAM )
import Bittide.DoubleBufferedRAM
import Bittide.SharedTypes
import Contranomy.Wishbone
import Data.Proxy
import Data.Type.Equality ((:~:)(Refl))

type DataLink frameWidth = Maybe (BitVector frameWidth)
type CalendarEntry memDepth = Index memDepth
type Calendar calDepth memDepth = Vec calDepth (CalendarEntry memDepth)
type ConfigurationPort calDepth memDepth = Maybe (Index calDepth, CalendarEntry memDepth)
Expand Down Expand Up @@ -102,3 +108,97 @@ scatterGatherEngine bootCalS bootCalG scatterConfig gatherConfig
gatherOut = doubleBufferedRAM (deepErrorX "gatherOut undefined")
newMetaCycleG readAddrSwitch writeFramePE
toSwitch = mux (register True $ (==0) <$> readAddrSwitch) (pure Nothing) $ Just <$> gatherOut

scatterUnit ::
(HiddenClockResetEnable dom, KnownNat memDepth, KnownNat frameWidth) =>
Vec memDepth (BitVector frameWidth) ->
CalendarConfig bytes addressWidth (CalendarEntry memDepth) ->
Signal dom (WishboneM2S bytes addressWidth) ->
Signal dom Bool ->
Signal dom (DataLink frameWidth) ->
Signal dom (Index memDepth) ->
(Signal dom (BitVector frameWidth), Signal dom (WishboneS2M bytes))
scatterUnit initMem calConfig wbIn calSwitch linkIn readAddr = (readOut, wbOut)
where
(writeAddr, metaCycle, wbOut) = mkCalendar calConfig calSwitch wbIn
writeOp = (\a b -> (a,) <$> b) <$> writeAddr <*> linkIn
readOut = doubleBufferedRAM initMem metaCycle readAddr writeOp

gatherUnit ::
(HiddenClockResetEnable dom, KnownNat memDepth, AtLeastOne frameWidth, AtLeastOne (DivRU frameWidth 8)) =>
Vec memDepth (BitVector frameWidth) ->
CalendarConfig bytes addressWidth (CalendarEntry memDepth) ->
Signal dom (WishboneM2S bytes addressWidth) ->
Signal dom Bool ->
Signal dom (WriteBits memDepth frameWidth) ->
Signal dom (ByteEnable (DivRU frameWidth 8)) ->
(Signal dom (DataLink frameWidth), Signal dom (WishboneS2M bytes))
gatherUnit initMem calConfig wbIn calSwitch writeOp byteEnables= (linkOut, wbOut)
where
(readAddr, metaCycle, wbOut) = mkCalendar calConfig calSwitch wbIn
linkOut = mux ((==0) <$> readAddr) (pure Nothing) $ Just <$> bramOut
bramOut = doubleBufferedRAMByteAddressable initMem metaCycle readAddr writeOp byteEnables

wbInterface ::
forall bytes addressWidth addresses .
(AtLeastOne addresses, AtLeast 2 addressWidth) =>
Index addresses ->
WishboneM2S bytes addressWidth ->
Bytes bytes ->
(WishboneS2M bytes, Index addresses, Maybe (Bytes bytes))
wbInterface addressRange WishboneM2S{..} readData = (WishboneS2M{readData, acknowledge, err}, memAddr, writeOp)
where
(alignedAddress, alignment) = split @_ @(addressWidth - 2) @2 addr
wordAligned = alignment == (0 :: BitVector 2)
err = (alignedAddress > resize (pack addressRange)) || not wordAligned
acknowledge = not err && strobe
wbAddr = unpack . resize $ pack alignedAddress
memAddr = wbAddr
writeOp | strobe && writeEnable && not err = Just writeData
| otherwise = Nothing

scatterUnitWB ::
forall dom memDepth awSU bsCal awCal .
(HiddenClockResetEnable dom, AtLeastOne memDepth, AtLeast 2 awSU) =>
Vec memDepth (BitVector 64) ->
CalendarConfig bsCal awCal (CalendarEntry memDepth) ->
Signal dom (WishboneM2S bsCal awCal) ->
Signal dom Bool ->
Signal dom (DataLink 64) ->
Signal dom (WishboneM2S 4 awSU) ->
(Signal dom (WishboneS2M 4), Signal dom (WishboneS2M bsCal))
scatterUnitWB initMem calConfig wbInCal calSwitch linkIn wbInSU = (wbOutSU, wbOutCal)
where
(wbOutSU, memAddr, _) = unbundle $ wbInterface (maxBound :: Index memDepth) <$> wbInSU <*> scatteredData
readAddr = (`shiftR` 1) <$> readAddr
(scatterUnitRead, wbOutCal) = scatterUnit initMem calConfig wbInCal calSwitch linkIn readAddr
(upper, lower) = unbundle $ split <$> scatterUnitRead
scatteredData = mux (bitToBool . lsb <$> memAddr) upper lower

gatherUnitWB ::
forall dom memDepth awSU bsCal awCal .
(HiddenClockResetEnable dom, AtLeastOne memDepth, AtLeast 2 awSU) =>
Vec memDepth (BitVector 64) ->
CalendarConfig bsCal awCal (CalendarEntry memDepth) ->
Signal dom (WishboneM2S bsCal awCal) ->
Signal dom Bool ->
Signal dom (WishboneM2S 4 awSU) ->
(Signal dom (DataLink 64), Signal dom (WishboneS2M 4), Signal dom (WishboneS2M bsCal))
gatherUnitWB initMem calConfig wbInCal calSwitch wbInSU = (linkOut, wbOutSU, wbOutCal)
where
(wbOutSU, memAddr, writeOp) = unbundle $ wbInterface (maxBound :: Index (memDepth * 2)) <$> wbInSU <*> pure 0b0
(writeAddr, upperSelected) = unbundle $ coerceIndexes <$> memAddr
(linkOut, wbOutCal) = gatherUnit initMem calConfig wbInCal calSwitch gatherWrite gatherByteEnables
gatherWrite = mkWrite <$> writeAddr <*> writeOp
gatherByteEnables = mkEnables <$> upperSelected <*> (busSelect <$> wbInSU)
mkWrite address (Just write) = Just (address, write ++# write)
mkWrite _ _ = Nothing
mkEnables selected byteEnables = if selected then byteEnables ++# 0b0 else 0b0 ++# byteEnables

coerceIndexes :: forall n . (AtLeastOne n) => (Index (n*2) -> (Index n, Bool))
coerceIndexes = case sameNat natA natB of
Just Refl -> bitCoerce
_ -> error "gatherUnitWB: Index coercion failed."
where
natA = Proxy @(CLog 2 (n*2))
natB = Proxy @(1 + CLog 2 n)
1 change: 1 addition & 0 deletions bittide/src/Bittide/SharedTypes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Data.Constraint
import Data.Constraint.Nat.Extra

type AtLeastOne n = (KnownNat n, 1 <= n)
type AtLeast atLeast n = (KnownNat n, atLeast <= n)
type Byte = BitVector 8
type Bytes n = BitVector (n*8)
type ByteEnable bytes = BitVector bytes
Expand Down

0 comments on commit c107ed3

Please sign in to comment.