clash-protocols
Safe HaskellNone
LanguageGHC2021

Protocols.Df

Description

Defines data structures and operators to create a Dataflow protocol that only carries data, no metadata. For documentation see:

Synopsis

Types

data Df (dom :: Domain) a Source #

Simple unidirectional valid-ready protocol.

Instances

Instances details
NFDataX dat => DfConv (Df dom dat) Source # 
Instance details

Defined in Protocols.DfConv

Associated Types

type Dom (Df dom dat) 
Instance details

Defined in Protocols.DfConv

type Dom (Df dom dat) = dom
type BwdPayload (Df dom dat) 
Instance details

Defined in Protocols.DfConv

type BwdPayload (Df dom dat) = ()
type FwdPayload (Df dom dat) 
Instance details

Defined in Protocols.DfConv

type FwdPayload (Df dom dat) = dat

Methods

toDfCircuit :: Proxy (Df dom dat) -> Circuit (Df (Dom (Df dom dat)) (FwdPayload (Df dom dat)), Reverse (Df (Dom (Df dom dat)) (BwdPayload (Df dom dat)))) (Df dom dat) Source #

fromDfCircuit :: Proxy (Df dom dat) -> Circuit (Df dom dat) (Df (Dom (Df dom dat)) (FwdPayload (Df dom dat)), Reverse (Df (Dom (Df dom dat)) (BwdPayload (Df dom dat)))) Source #

DfConv (Df dom a, Reverse (Df dom b)) Source # 
Instance details

Defined in Protocols.DfConv

Associated Types

type Dom (Df dom a, Reverse (Df dom b)) 
Instance details

Defined in Protocols.DfConv

type Dom (Df dom a, Reverse (Df dom b)) = dom
type BwdPayload (Df dom a, Reverse (Df dom b)) 
Instance details

Defined in Protocols.DfConv

type BwdPayload (Df dom a, Reverse (Df dom b)) = b
type FwdPayload (Df dom a, Reverse (Df dom b)) 
Instance details

Defined in Protocols.DfConv

type FwdPayload (Df dom a, Reverse (Df dom b)) = a

Methods

toDfCircuit :: Proxy (Df dom a, Reverse (Df dom b)) -> Circuit (Df (Dom (Df dom a, Reverse (Df dom b))) (FwdPayload (Df dom a, Reverse (Df dom b))), Reverse (Df (Dom (Df dom a, Reverse (Df dom b))) (BwdPayload (Df dom a, Reverse (Df dom b))))) (Df dom a, Reverse (Df dom b)) Source #

fromDfCircuit :: Proxy (Df dom a, Reverse (Df dom b)) -> Circuit (Df dom a, Reverse (Df dom b)) (Df (Dom (Df dom a, Reverse (Df dom b))) (FwdPayload (Df dom a, Reverse (Df dom b))), Reverse (Df (Dom (Df dom a, Reverse (Df dom b))) (BwdPayload (Df dom a, Reverse (Df dom b))))) Source #

(TestType a, KnownDomain dom) => Test (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Hedgehog.Internal

Methods

expectN :: (HasCallStack, MonadTest m) => Proxy (Df dom a) -> ExpectOptions -> SimulateFwdType (Df dom a) -> m (ExpectType (Df dom a)) Source #

Backpressure (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

Methods

boolsToBwd :: Proxy (Df dom a) -> [Bool] -> Bwd (Df dom a) Source #

(KnownDomain dom, NFDataX a, ShowX a, Show a) => Drivable (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

Associated Types

type ExpectType (Df dom a) 
Instance details

Defined in Protocols.Experimental.Df

type ExpectType (Df dom a) = [a]

Methods

toSimulateType :: Proxy (Df dom a) -> ExpectType (Df dom a) -> SimulateFwdType (Df dom a) Source #

fromSimulateType :: Proxy (Df dom a) -> SimulateFwdType (Df dom a) -> ExpectType (Df dom a) Source #

driveC :: SimulationConfig -> SimulateFwdType (Df dom a) -> Circuit () (Df dom a) Source #

sampleC :: SimulationConfig -> Circuit () (Df dom a) -> SimulateFwdType (Df dom a) Source #

(KnownDomain dom, NFDataX a, ShowX a, Show a) => Simulate (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

Associated Types

type SimulateFwdType (Df dom a) 
Instance details

Defined in Protocols.Experimental.Df

type SimulateFwdType (Df dom a) = [Maybe a]
type SimulateBwdType (Df dom a) 
Instance details

Defined in Protocols.Experimental.Df

type SimulateBwdType (Df dom a) = [Ack]
type SimulateChannels (Df dom a) 
Instance details

Defined in Protocols.Experimental.Df

type SimulateChannels (Df dom a) = 1

Methods

simToSigFwd :: Proxy (Df dom a) -> SimulateFwdType (Df dom a) -> Fwd (Df dom a) Source #

simToSigBwd :: Proxy (Df dom a) -> SimulateBwdType (Df dom a) -> Bwd (Df dom a) Source #

sigToSimFwd :: Proxy (Df dom a) -> Fwd (Df dom a) -> SimulateFwdType (Df dom a) Source #

sigToSimBwd :: Proxy (Df dom a) -> Bwd (Df dom a) -> SimulateBwdType (Df dom a) Source #

stallC :: SimulationConfig -> Vec (SimulateChannels (Df dom a)) (StallAck, [Int]) -> Circuit (Df dom a) (Df dom a) Source #

IdleCircuit (Df dom a) Source # 
Instance details

Defined in Protocols.Df

Methods

idleFwd :: Proxy (Df dom a) -> Fwd (Df dom a) Source #

idleBwd :: Proxy (Df dom a) -> Bwd (Df dom a) Source #

Protocol (Df dom a) Source # 
Instance details

Defined in Protocols.Df

Associated Types

type Fwd (Df dom a) 
Instance details

Defined in Protocols.Df

type Fwd (Df dom a) = Signal dom (Maybe a)
type Bwd (Df dom a) 
Instance details

Defined in Protocols.Df

type Bwd (Df dom a) = Signal dom Ack
type BwdPayload (Df dom dat) Source # 
Instance details

Defined in Protocols.DfConv

type BwdPayload (Df dom dat) = ()
type BwdPayload (Df dom a, Reverse (Df dom b)) Source # 
Instance details

Defined in Protocols.DfConv

type BwdPayload (Df dom a, Reverse (Df dom b)) = b
type Dom (Df dom dat) Source # 
Instance details

Defined in Protocols.DfConv

type Dom (Df dom dat) = dom
type Dom (Df dom a, Reverse (Df dom b)) Source # 
Instance details

Defined in Protocols.DfConv

type Dom (Df dom a, Reverse (Df dom b)) = dom
type FwdPayload (Df dom dat) Source # 
Instance details

Defined in Protocols.DfConv

type FwdPayload (Df dom dat) = dat
type FwdPayload (Df dom a, Reverse (Df dom b)) Source # 
Instance details

Defined in Protocols.DfConv

type FwdPayload (Df dom a, Reverse (Df dom b)) = a
type ExpectType (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

type ExpectType (Df dom a) = [a]
type SimulateBwdType (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

type SimulateBwdType (Df dom a) = [Ack]
type SimulateChannels (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

type SimulateChannels (Df dom a) = 1
type SimulateFwdType (Df dom a) Source # 
Instance details

Defined in Protocols.Experimental.Df

type SimulateFwdType (Df dom a) = [Maybe a]
type Bwd (Df dom a) Source # 
Instance details

Defined in Protocols.Df

type Bwd (Df dom a) = Signal dom Ack
type Fwd (Df dom a) Source # 
Instance details

Defined in Protocols.Df

type Fwd (Df dom a) = Signal dom (Maybe a)

Operations on Df protocol

empty :: forall (dom :: Domain) a. Circuit () (Df dom a) Source #

Never produce a value.

const :: forall (dom :: Domain) b a. HiddenReset dom => b -> Circuit (Df dom a) (Df dom b) Source #

Acknowledge but ignore data from LHS protocol. Send a static value b.

consume :: forall (dom :: Domain) a. HiddenReset dom => Circuit (Df dom a) () Source #

Always acknowledge and ignore values.

void :: forall (dom :: Domain) a. HiddenReset dom => Circuit (Df dom a) () Source #

Never acknowledge values.

pure :: forall a (dom :: Domain). a -> Circuit () (Df dom a) Source #

Drive a constant value composed of a.

map :: forall a b (dom :: Domain). (a -> b) -> Circuit (Df dom a) (Df dom b) Source #

Like map, but over payload (a) of a Df stream.

mapS :: forall (dom :: Domain) a b. Signal dom (a -> b) -> Circuit (Df dom a) (Df dom b) Source #

Like map, but can reason over signals.

bimap :: forall p a b c d (dom :: Domain). Bifunctor p => (a -> b) -> (c -> d) -> Circuit (Df dom (p a c)) (Df dom (p b d)) Source #

Like map, but over payload (a) of a Df stream.

bimapS :: forall p (dom :: Domain) a b c d. Bifunctor p => Signal dom (a -> b) -> Signal dom (c -> d) -> Circuit (Df dom (p a c)) (Df dom (p b d)) Source #

Like bimap, but can reason over signals.

fst :: forall (dom :: Domain) a b. Circuit (Df dom (a, b)) (Df dom a) Source #

Like fst, but over payload of a Df stream.

snd :: forall (dom :: Domain) a b. Circuit (Df dom (a, b)) (Df dom b) Source #

Like snd, but over payload of a Df stream.

mapMaybe :: forall a b (dom :: Domain). (a -> Maybe b) -> Circuit (Df dom a) (Df dom b) Source #

Like mapMaybe, but over payload (a) of a Df stream.

catMaybes :: forall (dom :: Domain) a. Circuit (Df dom (Maybe a)) (Df dom a) Source #

Like catMaybes, but over a Df stream.

Example:

>>> take 2 (simulateCS (catMaybes @C.System @Int) [Nothing, Just 1, Nothing, Just 3])
[1,3]

coerce :: forall a b (dom :: Domain). Coercible a b => Circuit (Df dom a) (Df dom b) Source #

Coerce the payload of a Df stream.

compressor Source #

Arguments

:: forall (dom :: Domain) s i o. (HiddenClockResetEnable dom, NFDataX s) 
=> s 
-> (s -> i -> (s, Maybe o))

Return Just when the compressed value is complete.

-> Circuit (Df dom i) (Df dom o) 

Takes one or more values from the left and "compresses" it into a single value that is occasionally sent to the right. Useful for taking small high-speed inputs (like bits from a serial line) and turning them into slower wide outputs (like 32-bit integers).

Example:

>>> accumulate xs x = let xs' = x:xs in if length xs' == 3 then ([], Just xs') else (xs', Nothing)
>>> circuit = C.exposeClockResetEnable (compressor @C.System [] accumulate)
>>> take 2 (simulateCSE circuit [(1::Int),2,3,4,5,6,7])
[[3,2,1],[6,5,4]]

expander Source #

Arguments

:: forall (dom :: Domain) i o s. (HiddenClockResetEnable dom, NFDataX s) 
=> s 
-> (s -> i -> (s, o, Bool))

Return True when you're finished with the current input value and are ready for the next one.

-> Circuit (Df dom i) (Df dom o) 

Takes a value from the left and "expands" it into one or more values that are sent off to the right. Useful for taking wide, slow inputs (like a stream of 32-bit integers) and turning them into a fast, narrow output (like a stream of bits).

Example:

>>> step index = if index == maxBound then (0, True) else (index + 1, False)
>>> expandVector index vec = let (index', done) = step index in (index', vec C.!! index, done)
>>> circuit = C.exposeClockResetEnable (expander @C.System (0 :: C.Index 3) expandVector)
>>> take 6 (simulateCSE circuit [1 :> 2 :> 3 :> Nil, 4 :> 5 :> 6 :> Nil])
[1,2,3,4,5,6]

compander Source #

Arguments

:: forall (dom :: Domain) i o s. (HiddenClockResetEnable dom, NFDataX s) 
=> s 
-> (s -> i -> (s, Maybe o, Bool))

Return True when you're finished with the current input value and are ready for the next one. Return Just to send the produced value off to the right.

-> Circuit (Df dom i) (Df dom o) 

Takes values from the left, possibly holding them there for a while while working on them, and occasionally sends values off to the right. Used to implement both expander and compressor, so you can use it when there's not a straightforward one-to-many or many-to-one relationship between the input and output streams.

filter :: forall (dom :: Domain) a. (a -> Bool) -> Circuit (Df dom a) (Df dom a) Source #

Like filter, but over a Df stream.

Example:

>>> take 3 (simulateCS (filter @C.System @Int (>5)) [1, 5, 7, 10, 3, 11])
[7,10,11]

filterS :: forall (dom :: Domain) a. Signal dom (a -> Bool) -> Circuit (Df dom a) (Df dom a) Source #

Like filter, but can reason over signals.

either :: forall a c b (dom :: Domain). (a -> c) -> (b -> c) -> Circuit (Df dom (Either a b)) (Df dom c) Source #

Like either, but over a Df stream.

eitherS :: forall (dom :: Domain) a c b. Signal dom (a -> c) -> Signal dom (b -> c) -> Circuit (Df dom (Either a b)) (Df dom c) Source #

Like either, but can reason over signals.

first :: forall p a b (dom :: Domain) c. Bifunctor p => (a -> b) -> Circuit (Df dom (p a c)) (Df dom (p b c)) Source #

Like first, but over payload of a Df stream.

firstS :: forall p (dom :: Domain) a b c. Bifunctor p => Signal dom (a -> b) -> Circuit (Df dom (p a c)) (Df dom (p b c)) Source #

Like first, but can reason over signals.

mapLeft :: forall a b (dom :: Domain) c. (a -> b) -> Circuit (Df dom (Either a c)) (Df dom (Either b c)) Source #

Like mapLeft, but over payload of a Df stream.

mapLeftS :: forall (dom :: Domain) a b c. Signal dom (a -> b) -> Circuit (Df dom (Either a c)) (Df dom (Either b c)) Source #

Like mapLeft, but can reason over signals.

second :: forall p b c (dom :: Domain) a. Bifunctor p => (b -> c) -> Circuit (Df dom (p a b)) (Df dom (p a c)) Source #

Like second, but over payload of a Df stream.

secondS :: forall p (dom :: Domain) b c a. Bifunctor p => Signal dom (b -> c) -> Circuit (Df dom (p a b)) (Df dom (p a c)) Source #

Like second, but can reason over signals.

mapRight :: forall b c (dom :: Domain) a. (b -> c) -> Circuit (Df dom (Either a b)) (Df dom (Either a c)) Source #

Like mapRight, but over payload of a Df stream.

mapRightS :: forall (dom :: Domain) b c a. Signal dom (b -> c) -> Circuit (Df dom (Either a b)) (Df dom (Either a c)) Source #

Like mapRight, but can reason over signals.

zipWith :: forall (dom :: Domain) a b c. (a -> b -> c) -> Circuit (Df dom a, Df dom b) (Df dom c) Source #

Like zipWith, but over two Df streams.

Example:

>>> take 3 (simulateCS (zipWith @C.System @Int (+)) ([1, 3, 5], [2, 4, 7]))
[3,7,12]

zipWithS :: forall (dom :: Domain) a b c. Signal dom (a -> b -> c) -> Circuit (Df dom a, Df dom b) (Df dom c) Source #

Like zipWith, but can reason over signals.

zip :: forall a b (dom :: Domain). Circuit (Df dom a, Df dom b) (Df dom (a, b)) Source #

Like zip, but over two Df streams.

partition :: forall (dom :: Domain) a. (a -> Bool) -> Circuit (Df dom a) (Df dom a, Df dom a) Source #

Like partition, but over Df streams

Example:

>>> let input = [1, 3, 5, 7, 9, 2, 11]
>>> let output = simulateCS (partition @C.System @Int (>5)) input
>>> B.bimap (take 3) (take 4) output
([7,9,11],[1,3,5,2])

partitionEithers :: forall (dom :: Domain) a b. Circuit (Df dom (Either a b)) (Df dom a, Df dom b) Source #

Like partitionEithers, but over Df streams

Example:

>>> let input = [Left 1, Right 'a', Left 2, Right 'b']
>>> let output = simulateCS (partitionEithers @C.System @Int @Char) input
>>> B.bimap (take 2) (take 2) output
([1,2],"ab")

partitionS :: forall (dom :: Domain) a. Signal dom (a -> Bool) -> Circuit (Df dom a) (Df dom a, Df dom a) Source #

Like partition, but can reason over signals.

route :: forall (n :: Nat) (dom :: Domain) a. KnownNat n => Circuit (Df dom (Index n, a)) (Vec n (Df dom a)) Source #

Route a Df stream to another corresponding to the index

Example:

>>> let input = [(0, 3), (0, 5), (1, 7), (2, 13), (1, 11), (2, 1)]
>>> let output = simulateCS (route @3 @C.System @Int) input
>>> fmap (take 2) output
[3,5] :> [7,11] :> [13,1] :> Nil

select :: forall (n :: Nat) (dom :: Domain) a. KnownNat n => Circuit (Vec n (Df dom a), Df dom (Index n)) (Df dom a) Source #

Select data from the channel indicated by the Df stream carrying Index n.

Example:

>>> let indices = [1, 1, 2, 0, 2]
>>> let dats = [8] :> [5, 7] :> [9, 1] :> Nil
>>> let output = simulateCS (select @3 @C.System @Int) (dats, indices)
>>> take 5 output
[5,7,9,8,1]

selectN :: forall (n :: Nat) (selectN :: Nat) (dom :: Domain) a. (HiddenClockResetEnable dom, KnownNat selectN, KnownNat n) => Circuit (Vec n (Df dom a), Df dom (Index n, Index selectN)) (Df dom a) Source #

Select selectN samples from channel n.

Example:

>>> let indices = [(0, 2), (1, 3), (0, 2)]
>>> let dats = [10, 20, 30, 40] :> [11, 22, 33] :> Nil
>>> let circuit = C.exposeClockResetEnable (selectN @2 @10 @C.System @Int)
>>> take 7 (simulateCSE circuit (dats, indices))
[10,20,11,22,33,30,40]

selectUntil :: forall (n :: Nat) (dom :: Domain) a. KnownNat n => (a -> Bool) -> Circuit (Vec n (Df dom a), Df dom (Index n)) (Df dom a) Source #

Selects samples from channel n until the predicate holds. The cycle in which the predicate turns true is included.

Example:

>>> let indices = [0, 0, 1, 2]
>>> let channel1 = [(10, False), (20, False), (30, True), (40, True)]
>>> let channel2 = [(11, False), (21, True)]
>>> let channel3 = [(12, False), (22, False), (32, False), (42, True)]
>>> let dats = channel1 :> channel2 :> channel3 :> Nil
>>> take 10 (simulateCS (selectUntil @3 @C.System @(Int, Bool) P.snd) (dats, indices))
[(10,False),(20,False),(30,True),(40,True),(11,False),(21,True),(12,False),(22,False),(32,False),(42,True)]

selectUntilS :: forall (n :: Nat) (dom :: Domain) a. KnownNat n => Signal dom (a -> Bool) -> Circuit (Vec n (Df dom a), Df dom (Index n)) (Df dom a) Source #

Like selectUntil, but can reason over signals.

fanin :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, 1 <= n) => (a -> a -> a) -> Circuit (Vec n (Df dom a)) (Df dom a) Source #

Merge data of multiple Df streams using a user supplied function

faninS :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, 1 <= n) => Signal dom (a -> a -> a) -> Circuit (Vec n (Df dom a)) (Df dom a) Source #

Like fanin, but can reason over signals.

mfanin :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, Monoid a, 1 <= n) => Circuit (Vec n (Df dom a)) (Df dom a) Source #

Merge data of multiple Df streams using Monoid's <>.

fanout :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, HiddenClockResetEnable dom, 1 <= n) => Circuit (Df dom a) (Vec n (Df dom a)) Source #

Copy data of a single Df stream to multiple. LHS will only receive an acknowledgement when all RHS receivers have acknowledged data.

bundleVec :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, 1 <= n) => Circuit (Vec n (Df dom a)) (Df dom (Vec n a)) Source #

Bundle a vector of Df streams into one.

unbundleVec :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, NFDataX a, HiddenClockResetEnable dom, 1 <= n) => Circuit (Df dom (Vec n a)) (Vec n (Df dom a)) Source #

Split up a Df stream of a vector into multiple independent Df streams.

roundrobin :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, HiddenClockResetEnable dom, 1 <= n) => Circuit (Df dom a) (Vec n (Df dom a)) Source #

Distribute data across multiple components on the RHS. Useful if you want to parallelize a workload across multiple (slow) workers. For optimal throughput, you should make sure workers can accept data every n cycles.

data CollectMode Source #

Collect modes for dataflow arbiters.

Constructors

NoSkip

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.

Skip

Collect in a round-robin fashion. If a source does not produce data, skip it and check the next source on the next cycle.

Parallel

Check all sources in parallel. Biased towards the first source. If the number of sources is high, this is more expensive than other modes.

roundrobinCollect :: forall (n :: Nat) (dom :: Domain) a. (KnownNat n, HiddenClockResetEnable dom, 1 <= n) => CollectMode -> Circuit (Vec n (Df dom a)) (Df dom a) Source #

Opposite of roundrobin. Useful to collect data from workers that only produce a result with an interval of n cycles.

registerFwd :: forall (dom :: Domain) a. (NFDataX a, HiddenClockResetEnable dom) => Circuit (Df dom a) (Df dom a) Source #

Place register on forward part of a circuit. This adds combinational delay on the backward path.

registerBwd :: forall (dom :: Domain) a. (NFDataX a, HiddenClockResetEnable dom) => Circuit (Df dom a) (Df dom a) Source #

Place register on backward part of a circuit. This adds combinational delay on the forward path.

fifo :: forall (dom :: Domain) a (depth :: Nat). (HiddenClockResetEnable dom, KnownNat depth, NFDataX a, 1 <= depth) => SNat depth -> Circuit (Df dom a) (Df dom a) Source #

A fifo buffer with user-provided depth. Uses blockram to store data. Can handle simultaneous write and read (full throughput rate).

toMaybe :: forall (dom :: Domain) a. Circuit (Df dom a) (CSignal dom (Maybe a)) Source #

Convert a Df stream to a Maybe stream. Never stalls LHS.

unsafeFromMaybe :: forall (n :: Nat) a (dom :: Domain). (HiddenClockResetEnable dom, NFDataX a, KnownNat n) => Circuit (CSignal dom (Maybe a)) (Df dom a, CSignal dom (Unsigned n)) Source #

Convert a Maybe stream to a Df stream. Not every Just is guaranteed to be forwarded to the RHS because of potential backpressure. The number of dropped Justs is exported as an unsigned number. Note that this circuit uses the clock supplied through the HiddenClockResetEnable constraint to latch the incoming Maybe values in case of backpressure from the RHS. This makes it adhere to the rules of the Df protocol.

Internals

forceResetSanity :: forall (dom :: Domain) a. (KnownDomain dom, HiddenReset dom) => Circuit (Df dom a) (Df dom a) Source #

Force a nack on the backward channel and no data on the forward channel if reset is asserted.