Skip to content

Commit

Permalink
Added Haddock documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
lmbollen committed Apr 8, 2022
1 parent c107ed3 commit 4c765a9
Showing 1 changed file with 75 additions and 16 deletions.
91 changes: 75 additions & 16 deletions bittide/src/Bittide/ScatterGather.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,42 +109,77 @@ scatterGatherEngine bootCalS bootCalG scatterConfig gatherConfig
newMetaCycleG readAddrSwitch writeFramePE
toSwitch = mux (register True $ (==0) <$> readAddrSwitch) (pure Nothing) $ Just <$> gatherOut


-- | Doublebuffered memory component that can be written to by a Bittide link, write address
-- of the incoming frame is determined by the scatterUnit's calendar. The buffers are swapped
-- at the beginning of each metacycle. Reading the buffer is done by supplying a read address.
-- Furthermore this component offers ports to control the incorporated calendar.
scatterUnit ::
(HiddenClockResetEnable dom, KnownNat memDepth, KnownNat frameWidth) =>
( HiddenClockResetEnable dom
, KnownNat memDepth
, KnownNat frameWidth) =>
-- | Initial contents of both memory buffers.
Vec memDepth (BitVector frameWidth) ->
-- | Configuration for the calendar.
CalendarConfig bytes addressWidth (CalendarEntry memDepth) ->
-- | Wishbone master-slave port for the calendar.
Signal dom (WishboneM2S bytes addressWidth) ->
-- | Swap active calendar and shadow calendar.
Signal dom Bool ->
-- | Incoming frame from Bittide link.
Signal dom (DataLink frameWidth) ->
-- | Read address.
Signal dom (Index memDepth) ->
-- | (Data at read address delayed 1 cycle, Wishbone slave-master from calendar)
(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

-- | Doublebuffered memory component that can be written to by a generic write operation, write address
-- of the incoming frame is determined by the scatterUnit's calendar. The buffers are swapped
-- at the beginning of each metacycle. Reading the buffer is done by supplying a read address.
-- Furthermore this component offers ports to control the incorporated calendar.
gatherUnit ::
(HiddenClockResetEnable dom, KnownNat memDepth, AtLeastOne frameWidth, AtLeastOne (DivRU frameWidth 8)) =>
( HiddenClockResetEnable dom
, KnownNat memDepth
, AtLeastOne frameWidth
, AtLeastOne (DivRU frameWidth 8)) =>
-- | Initial contents for both memory buffers
Vec memDepth (BitVector frameWidth) ->
-- | Configuration for the calendar.
CalendarConfig bytes addressWidth (CalendarEntry memDepth) ->
-- | Wishbone master-slave port for the calendar.
Signal dom (WishboneM2S bytes addressWidth) ->
-- | Swap active calendar and shadow calendar.
Signal dom Bool ->
-- | Generic write operation writing a frame.
Signal dom (WriteBits memDepth frameWidth) ->
-- | Byte enable for write operation.
Signal dom (ByteEnable (DivRU frameWidth 8)) ->
-- | (Transmitted frame to Bittide Link, Wishbone slave-master from calendar)
(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

-- | Wishbone interface for the scatterUnit and gatherUnit. It makes the scatter and gather
-- unit, which operate on 64 bit frames, addressable via a 32 bit wishbone bus.
wbInterface ::
forall bytes addressWidth addresses .
(AtLeastOne addresses, AtLeast 2 addressWidth) =>
( AtLeastOne addresses
, AtLeast 2 addressWidth) =>
-- | Maximum address of the respective memory element as seen from the wishbone side.
Index addresses ->
-- | Wishbone master - slave data.
WishboneM2S bytes addressWidth ->
-- | Read data to be send to over the slave-master port.
Bytes bytes ->
-- | (slave - master data, read address memory element, write data memory element)
(WishboneS2M bytes, Index addresses, Maybe (Bytes bytes))
wbInterface addressRange WishboneM2S{..} readData = (WishboneS2M{readData, acknowledge, err}, memAddr, writeOp)
where
Expand All @@ -157,36 +192,59 @@ wbInterface addressRange WishboneM2S{..} readData = (WishboneS2M{readData, ackno
writeOp | strobe && writeEnable && not err = Just writeData
| otherwise = Nothing

-- | Wishbone addressable scatterUnit, the wishbone port can read the data from this
-- memory element as if it has a 32 bit port by selecting the upper 32 or lower 32 bits
-- of the read data.
scatterUnitWB ::
forall dom memDepth awSU bsCal awCal .
(HiddenClockResetEnable dom, AtLeastOne memDepth, AtLeast 2 awSU) =>
( HiddenClockResetEnable dom
, AtLeastOne memDepth
, AtLeast 2 awSU) =>
-- | Initial contents for both memory buffers
Vec memDepth (BitVector 64) ->
-- | Configuration for the calendar.
CalendarConfig bsCal awCal (CalendarEntry memDepth) ->
-- | Wishbone master - slave data calendar.
Signal dom (WishboneM2S bsCal awCal) ->
-- | Swap active calendar and shadow calendar.
Signal dom Bool ->
-- | Incoming frame from Bittide link.
Signal dom (DataLink 64) ->
-- | Wishbone master-slave port scatterUnit.
Signal dom (WishboneM2S 4 awSU) ->
-- | (slave - master data scatterUnit , slave - master data calendar)
(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
(wbOutSU, memAddr, _) = unbundle $ wbInterface maxBound <$> wbInSU <*> scatteredData
(readAddr, upperSelected) = unbundle $ coerceIndexes <$> memAddr
(scatterUnitRead, wbOutCal) = scatterUnit initMem calConfig wbInCal calSwitch linkIn readAddr
(upper, lower) = unbundle $ split <$> scatterUnitRead
scatteredData = mux (bitToBool . lsb <$> memAddr) upper lower
scatteredData = mux upperSelected upper lower

-- | Wishbone addressable gatherUnit, the wishbone port can write data to this
-- memory element as if it has a 32 bit port by controlling the byte enables of the
-- gatherUnit based on the third bit.
gatherUnitWB ::
forall dom memDepth awSU bsCal awCal .
(HiddenClockResetEnable dom, AtLeastOne memDepth, AtLeast 2 awSU) =>
( HiddenClockResetEnable dom
, AtLeastOne memDepth
, AtLeast 2 awSU) =>
-- | Initial contents for both memory buffers
Vec memDepth (BitVector 64) ->
-- | Configuration for the calendar.
CalendarConfig bsCal awCal (CalendarEntry memDepth) ->
-- | Wishbone master - slave data calendar.
Signal dom (WishboneM2S bsCal awCal) ->
-- | Swap active calendar and shadow calendar.
Signal dom Bool ->
-- | Wishbone master-slave port gatherUnit.
Signal dom (WishboneM2S 4 awSU) ->
-- | (slave - master data gatherUnit , slave - master data calendar)
(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
(wbOutSU, memAddr, writeOp) = unbundle $ wbInterface maxBound <$> wbInSU <*> pure 0b0
(writeAddr, upperSelected) = unbundle $ coerceIndexes <$> memAddr
(linkOut, wbOutCal) = gatherUnit initMem calConfig wbInCal calSwitch gatherWrite gatherByteEnables
gatherWrite = mkWrite <$> writeAddr <*> writeOp
Expand All @@ -195,10 +253,11 @@ gatherUnitWB initMem calConfig wbInCal calSwitch wbInSU = (linkOut, wbOutSU, wbO
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)
-- | Coerces an index of size (n*2) to index n with the lower bit as seperate boolean.
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)

0 comments on commit 4c765a9

Please sign in to comment.