Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PacketStream protocol. #85

Merged
merged 63 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
b3b0ad6
Add PacketStream protocol.
rowanG077 Jul 3, 2024
5fc350d
Implement IdleCircuit for PacketStream
t-wallet Jul 18, 2024
0ac3741
Add top level PacketStream module
t-wallet Jul 18, 2024
c589106
fix haddock
t-wallet Jul 18, 2024
22db469
(de)packetizer tests and split into two files
t-wallet Jul 19, 2024
2c3150c
Hide submodules and improve documentation
t-wallet Jul 22, 2024
61db3b6
optimize packetizeFromDfT
t-wallet Jul 22, 2024
6c5b6dd
Remove outdated comment
t-wallet Jul 22, 2024
4971dc7
Clean up tests and add sensible generators
t-wallet Jul 22, 2024
9792d7d
formatting
t-wallet Jul 22, 2024
6c1f349
re-add tests
t-wallet Jul 22, 2024
0b486f4
Optimize packetizer
t-wallet Jul 26, 2024
18ca61c
Simply/optimize downConverter
t-wallet Jul 29, 2024
9758a61
Run formatter
t-wallet Jul 31, 2024
df192db
Generate less input for PacketStream tests
t-wallet Jul 31, 2024
48af732
Remove redundant imports
t-wallet Jul 31, 2024
0c64db8
Add first version of generic PacketStream delay circuit
t-wallet Aug 2, 2024
589de45
DownConverter arbitrary metadata support + output data width may be a…
t-wallet Aug 2, 2024
d33ab4c
UpConverter arbitrary metadata support + output data width may be any…
t-wallet Aug 2, 2024
075134a
Fix haddock
t-wallet Aug 2, 2024
2e8720b
Fix problematic tests (?)
t-wallet Aug 2, 2024
a2c3e4f
Add PacketStream generic transfer delay circuit
t-wallet Aug 14, 2024
9bafbe4
Add dropTailC
t-wallet Aug 14, 2024
c23be40
Add component that zeroes out all invalid bytes
t-wallet Aug 14, 2024
2e8ee54
Temporarily remove dropTailC until Protocols.Plugin is moved
t-wallet Aug 19, 2024
3ed90f2
Optimize depacketizer
t-wallet Aug 19, 2024
8715163
Add haxiom module
t-wallet Aug 20, 2024
a8314d3
formatting
t-wallet Aug 20, 2024
8d9d148
Depacketizer: remove redundant buffer
t-wallet Aug 20, 2024
47188c5
Optimize depacketizeToDfC
t-wallet Aug 21, 2024
cf67944
Formatting
t-wallet Aug 21, 2024
9bae9d8
Improve documentation
t-wallet Aug 22, 2024
7d9df31
Export useful testing functions and generators via Protocols.PacketSt…
t-wallet Aug 27, 2024
b9376b7
Rename packetizer model functions
t-wallet Aug 27, 2024
9138b2d
Add sensible DfConv functions
t-wallet Aug 27, 2024
0d40b6f
Export chopBy
t-wallet Aug 28, 2024
250428a
Allow user to pass custom packet generator to genPackets
t-wallet Aug 30, 2024
62365f6
Optimize delay circuit
t-wallet Sep 3, 2024
3e8636d
Add delayStream id test
t-wallet Sep 3, 2024
8ddf374
Add dropTailC
t-wallet Sep 9, 2024
cc71314
Fix typos in dropTailC tests
t-wallet Sep 9, 2024
f2bdeaf
Implement more basic operations
t-wallet Sep 13, 2024
7aa0c17
Add autoreg instances
t-wallet Sep 14, 2024
1f60325
Slap unsafe on abortOnBackpressureC
t-wallet Sep 16, 2024
df5fd6d
Add unsafe version of upConverterC
t-wallet Sep 23, 2024
5adc393
PacketStream: support zero-byte transfers. (#122)
t-wallet Oct 10, 2024
1c39ebb
Adapt to new repo structure
t-wallet Oct 10, 2024
9ba7c69
downConverterC changes.
t-wallet Oct 18, 2024
ad75ad0
Prefer use of deepErrorX over undefined
t-wallet Oct 18, 2024
c14b940
Converters: patch up documentation
t-wallet Oct 18, 2024
4d161eb
Add copyright, license and maintainer attributes to all PacketStream …
t-wallet Oct 18, 2024
399ae17
Fix PacketFifo bug
t-wallet Oct 25, 2024
f77599e
Fix CSignal simulation functions
t-wallet Oct 25, 2024
c897b83
Remove global constraint solver iterations and unused code
t-wallet Oct 28, 2024
1309de1
Remove null-byte restriction
t-wallet Nov 8, 2024
d855b6b
Add generic padding stripper
t-wallet Nov 30, 2024
8038001
Handle review comments 1
t-wallet Dec 2, 2024
f44da8b
Improve depacketizer/packetizer testing
t-wallet Dec 13, 2024
d673a9d
Converters: remove unneeded constraints
t-wallet Dec 13, 2024
c70f77d
Base: small documentation improvements
t-wallet Dec 13, 2024
c94fc47
Packet arbiter improvements
t-wallet Dec 13, 2024
f09558d
Fix spelling mistakes
t-wallet Dec 13, 2024
b3bd8f3
Temporarily remove dropTailC and delayStreamC
t-wallet Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions clash-protocols/clash-protocols.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ library
, clash-protocols-base
, circuit-notation
, clash-prelude-hedgehog
, constraints
, data-default ^>= 0.7.1.1
, deepseq
, extra
Expand Down Expand Up @@ -144,6 +145,16 @@ library
Protocols.Axi4.WriteAddress
Protocols.Axi4.WriteData
Protocols.Axi4.WriteResponse
Protocols.PacketStream
Protocols.PacketStream.Base
Protocols.PacketStream.AsyncFifo
Protocols.PacketStream.Converters
Protocols.PacketStream.Depacketizers
Protocols.PacketStream.Hedgehog
Protocols.PacketStream.PacketFifo
Protocols.PacketStream.Packetizers
Protocols.PacketStream.Padding
Protocols.PacketStream.Routing
Protocols.Df
Protocols.DfConv
Protocols.Hedgehog
Expand All @@ -166,6 +177,9 @@ library
autogen-modules: Paths_clash_protocols

other-modules:
Data.Constraint.Nat.Extra
Data.Maybe.Extra
Clash.Sized.Vector.Extra
Paths_clash_protocols
Protocols.Hedgehog.Types
Protocols.Internal.Types
Expand All @@ -179,6 +193,7 @@ test-suite unittests
ghc-options: -threaded -with-rtsopts=-N
main-is: unittests.hs
other-modules:
Tests.Haxioms
Tests.Protocols
Tests.Protocols.Df
Tests.Protocols.DfConv
Expand All @@ -187,6 +202,16 @@ test-suite unittests
Tests.Protocols.Plugin
Tests.Protocols.Vec
Tests.Protocols.Wishbone
Tests.Protocols.PacketStream
Tests.Protocols.PacketStream.AsyncFifo
Tests.Protocols.PacketStream.Base
Tests.Protocols.PacketStream.Converters
Tests.Protocols.PacketStream.Depacketizers
Tests.Protocols.PacketStream.Packetizers
Tests.Protocols.PacketStream.PacketFifo
Tests.Protocols.PacketStream.Padding
Tests.Protocols.PacketStream.Routing

Util

build-depends:
Expand Down
36 changes: 36 additions & 0 deletions clash-protocols/src/Clash/Sized/Vector/Extra.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{-# LANGUAGE NoImplicitPrelude #-}

module Clash.Sized.Vector.Extra (
dropLe,
takeLe,
) where

import Clash.Prelude

-- | Like 'drop' but uses a 'Data.Type.Ord.<=' constraint
dropLe ::
forall
(n :: Nat)
(m :: Nat)
(a :: Type).
(n <= m) =>
-- | How many elements to take
SNat n ->
-- | input vector
Vec m a ->
Vec (m - n) a
dropLe SNat vs = leToPlus @n @m $ dropI vs

-- | Like 'take' but uses a 'Data.Type.Ord.<=' constraint
takeLe ::
forall
(n :: Nat)
(m :: Nat)
(a :: Type).
(n <= m) =>
-- | How many elements to take
SNat n ->
-- | input vector
Vec m a ->
Vec n a
takeLe SNat vs = leToPlus @n @m $ takeI vs
35 changes: 35 additions & 0 deletions clash-protocols/src/Data/Constraint/Nat/Extra.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{-# LANGUAGE AllowAmbiguousTypes #-}

{-
NOTE [constraint solver addition]

The functions in this module enable us introduce trivial constraints that are not
solved by the constraint solver.
-}
module Data.Constraint.Nat.Extra where

import Clash.Prelude
import Data.Constraint
import Unsafe.Coerce (unsafeCoerce)

{- | Postulates that multiplying some number /a/ by some constant /b/, and
subsequently dividing that result by /b/ equals /a/.
-}
cancelMulDiv :: forall a b. (1 <= b) => Dict (DivRU (a * b) b ~ a)
cancelMulDiv = unsafeCoerce (Dict :: Dict (0 ~ 0))

-- | if (1 <= b) then (Mod a b + 1 <= b)
leModulusDivisor :: forall a b. (1 <= b) => Dict (Mod a b + 1 <= b)
leModulusDivisor = unsafeCoerce (Dict :: Dict (0 <= 0))

-- | if (1 <= a) and (1 <= b) then (1 <= DivRU a b)
strictlyPositiveDivRu :: forall a b. (1 <= a, 1 <= b) => Dict (1 <= DivRU a b)
strictlyPositiveDivRu = unsafeCoerce (Dict :: Dict (0 <= 0))

-- | if (1 <= a) then (b <= ceil(b/a) * a)
leTimesDivRu :: forall a b. (1 <= a) => Dict (b <= a * DivRU b a)
leTimesDivRu = unsafeCoerce (Dict :: Dict (0 <= 0))

-- | if (1 <= a) then (a * ceil(b/a) ~ b + Mod (a - Mod b a) a)
eqTimesDivRu :: forall a b. (1 <= a) => Dict (a * DivRU b a ~ b + Mod (a - Mod b a) a)
eqTimesDivRu = unsafeCoerce (Dict :: Dict (0 ~ 0))
8 changes: 8 additions & 0 deletions clash-protocols/src/Data/Maybe/Extra.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Data.Maybe.Extra (
toMaybe,
) where

-- | Wrap a value in a @Just@ if @True@
toMaybe :: Bool -> a -> Maybe a
toMaybe True x = Just x
toMaybe False _ = Nothing
16 changes: 9 additions & 7 deletions clash-protocols/src/Protocols/Df.hs
Original file line number Diff line number Diff line change
Expand Up @@ -804,16 +804,18 @@ roundrobin =
in
(i1, (Ack ack, datOut1))

-- | Collect mode in 'roundrobinCollect'
-- | Collect modes for dataflow arbiters.
data CollectMode
= -- | Collect in a /roundrobin/ fashion. If a component does not produce
-- data, wait until it does.
= -- | Collect in a /round-robin/ fashion. If a source does not produce
-- data, wait until it does. Use with care, as there is a risk of
-- starvation if a selected source is idle for a long time.
NoSkip
| -- | Collect in a /roundrobin/ fashion. If a component does not produce
-- data, skip it and check the next component on the next cycle.
| -- | Collect in a /round-robin/ fashion. If a source does not produce
-- data, skip it and check the next source on the next cycle.
Skip
| -- | Check all components in parallel. Biased towards the /last/ Df
-- channel.
| -- | Check all sources in parallel. Biased towards the /last/ source.
-- If the number of sources is high, this is more expensive than other
-- modes.
Parallel

{- | Opposite of 'roundrobin'. Useful to collect data from workers that only
Expand Down
2 changes: 1 addition & 1 deletion clash-protocols/src/Protocols/DfConv.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ fanout ::
, FwdPayload dfA ~ FwdPayload dfB
, NFDataX (FwdPayload dfA)
, KnownNat numB
, numB ~ (decNumB + 1)
, 1 <= numB
) =>
Proxy dfA ->
Proxy dfB ->
Expand Down
4 changes: 2 additions & 2 deletions clash-protocols/src/Protocols/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

-- | Protocol-agnostic acknowledgement
newtype Ack = Ack Bool
deriving (Generic, C.NFDataX, Show, C.Bundle, Eq, Ord)

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.2.8 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.2.8 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.4.8 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.4.8 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.6.4 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

Check warning on line 62 in clash-protocols/src/Protocols/Internal.hs

View workflow job for this annotation

GitHub Actions / Cabal tests - ghc 9.6.4 / clash 1.8.1

• Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled

-- | Acknowledge. Used in circuit-notation plugin to drive ignore components.
instance Default Ack where
Expand Down Expand Up @@ -306,7 +306,7 @@
type SimulateChannels (CSignal dom a) = 1

simToSigFwd Proxy list = C.fromList_lazy list
simToSigBwd Proxy () = def
simToSigBwd Proxy () = pure ()
sigToSimFwd Proxy sig = C.sample_lazy sig
sigToSimBwd Proxy _ = ()

Expand All @@ -324,7 +324,7 @@
in Circuit (\_ -> ((), fwd1))

sampleC SimulationConfig{resetCycles, ignoreReset} (Circuit f) =
let sampled = CE.sample_lazy (snd (f ((), def)))
let sampled = CE.sample_lazy (snd (f ((), pure ())))
in if ignoreReset then drop resetCycles sampled else sampled

{- | Simulate a circuit. Includes samples while reset is asserted.
Expand Down
48 changes: 48 additions & 0 deletions clash-protocols/src/Protocols/PacketStream.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{- |
Copyright : (C) 2024, QBayLogic B.V.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <[email protected]>
Provides the PacketStream protocol, a simple streaming protocol for transferring packets of data between components.
Apart from the protocol definition, some components, all of which are generic in @dataWidth@, are also provided:
1. Several small utilities such as filtering a stream based on its metadata.
2. Fifos
3. Components which upsize or downsize @dataWidth@
4. Components which read from the stream (depacketizers)
5. Components which write to the stream (packetizers)
6. Components which split and merge a stream based on its metadata
-}
module Protocols.PacketStream (
module Protocols.PacketStream.Base,

-- * Fifos
module Protocols.PacketStream.PacketFifo,
module Protocols.PacketStream.AsyncFifo,

-- * Converters
module Protocols.PacketStream.Converters,

-- * Depacketizers
module Protocols.PacketStream.Depacketizers,

-- * Packetizers
module Protocols.PacketStream.Packetizers,

-- * Padding removal
module Protocols.PacketStream.Padding,

-- * Routing components
module Protocols.PacketStream.Routing,
)
where

import Protocols.PacketStream.AsyncFifo
import Protocols.PacketStream.Base
import Protocols.PacketStream.Converters
import Protocols.PacketStream.Depacketizers
import Protocols.PacketStream.PacketFifo
import Protocols.PacketStream.Packetizers
import Protocols.PacketStream.Padding
import Protocols.PacketStream.Routing
65 changes: 65 additions & 0 deletions clash-protocols/src/Protocols/PacketStream/AsyncFifo.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_HADDOCK hide #-}

{- |
Copyright : (C) 2024, QBayLogic B.V.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <[email protected]>

Provides `asyncFifoC` for crossing clock domains in the packet stream protocol.
-}
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

{- | Asynchronous FIFO circuit that can be used to safely cross clock domains.
Uses `Clash.Explicit.Prelude.asyncFIFOSynchronizer` internally.
-}
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) =>
-- | 2^depth is the number of elements this component can store
SNat depth ->
-- | Clock signal in the write domain
Clock wDom ->
-- | Reset signal in the write domain
Reset wDom ->
-- | Enable signal in the write domain
Enable wDom ->
-- | Clock signal in the read domain
Clock rDom ->
-- | Reset signal in the read domain
Reset rDom ->
-- | Enable signal in the read domain
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
-- If the FIFO is empty, we output Nothing. Else, we output the oldest element.
fwdOut = toMaybe <$> notEmpty <*> element
-- Assert backpressure when the FIFO is full.
bwdOut = PacketStreamS2M . not <$> isFull
-- Next component is ready to read if the fifo is not empty and it does not assert backpressure.
readReq = notEmpty .&&. _ready <$> bwdIn
Loading
Loading