You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -22,12 +22,12 @@ A battery-included library for writing on-chip protocols, such as AMBA AXI and A
22
22
`clash-protocols` exists to make it easy to develop and use on-chip communication protocols, with a focus on protocols in need of bidirectional communication, such as _AMBA AXI_. To familiarize yourself with `clash-protocols`, read [hackage.haskell.org/package/clash-protocols](http://hackage.haskell.org/package/clash-protocols). To read the next section, read at least:
23
23
24
24
*`Protocols`
25
-
*`Protocols.Df.Simple`
25
+
*`Protocols.Df`
26
26
27
-
The next section will guide you through the creation of a single `Dfs` based circuit.
27
+
The next section will guide you through the creation of a single `Df` based circuit.
28
28
29
-
# Using `Dfs`/`Df``Circuit`s
30
-
The basic handshaking of `Dfs` and `Df`are heavily inspired by _AMBA AXI_:
29
+
# Using `Df``Circuit`s
30
+
The basic handshaking of `Df`is heavily inspired by _AMBA AXI_:
31
31
32
32
*`Df` circuits _send_ data to their right hand side
33
33
*`Df` circuits _receive_ data from their left hand side.
@@ -36,7 +36,7 @@ The basic handshaking of `Dfs` and `Df` are heavily inspired by _AMBA AXI_:
36
36
37
37
## Invariants
38
38
39
-
The protocols `Df`and `Dfs` impose a contract each component should follow. These are, where possible, checked by the various test harnesses in `Protocols.Hedgehog`.
39
+
The protocols `Df`imposes a contract each component should follow. These are, where possible, checked by the various test harnesses in `Protocols.Hedgehog`.
40
40
41
41
*_Fwd a_ cannot depend on the _Bwd a_. In other words, deciding whether or not to send data cannot depend on the acknowledgment of that same data.
42
42
@@ -105,7 +105,7 @@ should be deasserted as follows: `a`, `b,` `c`, `d`/`e`, `f`. Resets might also
105
105
This order is imposed by the fact that there is an invariant stating a component in reset must not acknowledge data while in reset, but there is - for performance reasons - no invariant stating a component must not send data while in reset.
106
106
107
107
## Tutorial: `catMaybes`
108
-
At this point you should have familiarized with the basic structures of the `Dfs`: its dataconstructors (`Data`, `NoData`, and `Ack`) and its invariants, as well as the structure of a `Circuit` itself. To quickly try things it's useful to keep a repl around. With `stack`:
108
+
At this point you should have familiarized with the basic structures of the `Df`: its dataconstructors (`Data`, `NoData`, and `Ack`) and its invariants, as well as the structure of a `Circuit` itself. To quickly try things it's useful to keep a repl around. With `stack`:
109
109
110
110
```
111
111
stack exec --package clash-protocols ghci
@@ -122,7 +122,7 @@ Both should give you the same shell. Import the necessary modules:
122
122
123
123
```bash
124
124
>>> import qualified Clash.Prelude as C
125
-
>>> import qualified Protocols.Df.Simple as Dfs
125
+
>>> import qualified Protocols.Df as Df
126
126
```
127
127
128
128
You should now be able to query various things. For example:
@@ -140,21 +140,21 @@ module CatMaybes where
140
140
141
141
importProtocols
142
142
importqualifiedClash.PreludeasC
143
-
importqualifiedProtocols.Df.SimpleasDfs
143
+
importqualifiedProtocols.DfasDf
144
144
```
145
145
146
146
Then, we define the typeand name of the component we'd like to write:
147
147
148
148
```haskell
149
-
catMaybes::Circuit (Dfsdom (Maybea)) (Dfsdoma)
149
+
catMaybes::Circuit (Dfdom (Maybea)) (Dfdoma)
150
150
```
151
151
152
-
I.e., a circuit that takes a `Dfs` stream of `Maybe a` on the left hand side (LHS) and produces a stream of`a` on the right hand side (RHS).Note that the data carried on `Dfs`s _forward_ path very much looks like a `Maybe` in the first place:
152
+
I.e., a circuit that takes a `Df` stream of `Maybe a` on the left hand side (LHS) and produces a stream of`a` on the right hand side (RHS).Note that the data carried on `Df`s _forward_ path very much looks like a `Maybe` in the first place:
153
153
154
154
```
155
-
>>> :kind! Fwd (Dfs C.System Int)
155
+
>>> :kind! Fwd (Df C.System Int)
156
156
..
157
-
= Signal "System" (Dfs.Data Int)
157
+
= Signal "System" (Df.Data Int)
158
158
```
159
159
160
160
..because `Data Int` itself has two constructors: `Data Int` and `NoData`. In effect, we'd like squash `Data (Just a)` into `Data a`, and `Data Nothing` into `NoData`. Not unlike the way [join](https://hackage.haskell.org/package/base-4.14.0.0/docs/Control-Monad.html#v:join) would work on two `Maybe`s.
@@ -171,8 +171,8 @@ At this point, GHC will tell us:
This is something we can write, surely! If the LHS does not send data, there's not much we can do. We send `NoData` to the RHS and send a /nack/:
231
231
232
232
```haskell
233
-
go (Dfs.NoData, _) = (Dfs.AckFalse, Dfs.NoData)
233
+
go (Df.NoData, _) = (Df.AckFalse, Df.NoData)
234
234
```
235
235
236
236
If we _do_ receive data from the LHS but it turns out to be _Nothing_, we'd like to acknowledge that we received the data and send `NoData` to the RHS:
237
237
238
238
```haskell
239
-
go (Dfs.DataNothing, _) = (Dfs.AckTrue, Dfs.NoData)
239
+
go (Df.DataNothing, _) = (Df.AckTrue, Df.NoData)
240
240
```
241
241
242
242
Finally, if the LHS sends data and it turns out to be a _Just_, we'd like to acknowledge that we received it and pass it onto the RHS. But we should be careful, we should only acknowledge it if our RHS received our data! In effect, we can just passthrough the ack:
The explanation for the definition is out of scope for this tutorial, but it basically says: this generator generates a list with 0 to 100 elements, each a `Just` or a `Nothing`. If it is a `Just` it will contain an `Int` between 10 and 20. If you'd like to learn more about Hedgehog head over to [hackage.haskell.org/package/hedgehog](http://hackage.haskell.org/package/hedgehog).
270
270
271
-
For `Dfs` circuits we can define a pretty strong property: a `Circuit (Dfs dom a) (Dfs dom a)` is functionally the same as a function `[a] -> [a]` if we strip all the backpressure and `Signal` abstractions. Similarly, we for our `Circuit (Dfs dom (Maybe a)) (Dfs dom a)` our _pure model_ would be `[Maybe a] -> [a]`, i.e. [`Data.catMaybes`](https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Maybe.html#v:catMaybes)!
271
+
For `Df` circuits we can define a pretty strong property: a `Circuit (Df dom a) (Df dom a)` is functionally the same as a function `[a] -> [a]` if we strip all the backpressure and `Signal` abstractions. Similarly, we for our `Circuit (Df dom (Maybe a)) (Df dom a)` our _pure model_ would be `[Maybe a] -> [a]`, i.e. [`Data.catMaybes`](https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Maybe.html#v:catMaybes)!
272
272
273
273
The function `Protocols.Hedgehog.idWithModel` takes advantage of exactly that fact. You tell it:
274
274
@@ -292,7 +292,7 @@ prop_catMaybes =
292
292
(catMaybes @C.System)
293
293
```
294
294
295
-
From that point on, it will do the rest. By driving the circuit with arbitrary input and backpressure (among other things), it effectively tests whether a circuit implements the invariants of the `Dfs` protocol and whether it is (functionally) equivalent to its pure model. To actually run the tests we need some more boilerplate:
295
+
From that point on, it will do the rest. By driving the circuit with arbitrary input and backpressure (among other things), it effectively tests whether a circuit implements the invariants of the `Df` protocol and whether it is (functionally) equivalent to its pure model. To actually run the tests we need some more boilerplate:
296
296
297
297
298
298
@@ -345,13 +345,13 @@ We'll try and upstream these patches.
345
345
346
346
----------------
347
347
348
-
Writing a `Dfs` component can be tricky business. Even for relatively simple circuits such as `catMaybes` it's easy to send a wrong acknowledgment. The test harness is supposed to catch this, but its output isn't always easy to parse. We'll go over a few common mistakes.
348
+
Writing a `Df` component can be tricky business. Even for relatively simple circuits such as `catMaybes` it's easy to send a wrong acknowledgment. The test harness is supposed to catch this, but its output isn't always easy to parse. We'll go over a few common mistakes.
349
349
350
350
Let's introduce one:
351
351
352
352
```diff
353
-
- go (Dfs.Data Nothing, _) = (Dfs.Ack True, Dfs.NoData)
354
-
+ go (Dfs.Data Nothing, _) = (Dfs.Ack False, Dfs.NoData)
353
+
- go (Df.Data Nothing, _) = (Df.Ack True, Df.NoData)
354
+
+ go (Df.Data Nothing, _) = (Df.Ack False, Df.NoData)
355
355
```
356
356
357
357
Rerunning the tests will give us a big error, which starts out as:
@@ -448,8 +448,8 @@ The test tells us that no output was sampled, even though it expected to sample
448
448
Let's revert the "mistake" we made and make another:
Again, we get a pretty big error report. Let's skip right to the interesting bits:
@@ -476,15 +476,15 @@ Circuit did not produce enough output. Expected 1 more values. Sampled only 0:
476
476
[]
477
477
```
478
478
479
-
In this case, Hedgehog pretty much constrained us to pretty much one case in our implementation: the one where it matches on `Dfs.Data (Just d)`. Weirdly, no backpressure was needed to trigger this error, but we still see dropped values. This usually means we generated an _ack_ while the reset was asserted. And sure enough, we don't check for this. (Note that the "right" implementation moved the responsibility of this problem to the component on the RHS, hence not failing.)
479
+
In this case, Hedgehog pretty much constrained us to pretty much one case in our implementation: the one where it matches on `Df.Data (Just d)`. Weirdly, no backpressure was needed to trigger this error, but we still see dropped values. This usually means we generated an _ack_ while the reset was asserted. And sure enough, we don't check for this. (Note that the "right" implementation moved the responsibility of this problem to the component on the RHS, hence not failing.)
480
480
481
-
At this point it might be tempting to use `Dfs.forceAckLow` to force proper reset behavior. To do so, apply the patch:
481
+
At this point it might be tempting to use `Df.forceAckLow` to force proper reset behavior. To do so, apply the patch:
482
482
483
483
```diff
484
-
- catMaybes :: Circuit (Dfs dom (Maybe a)) (Dfs dom a)
484
+
- catMaybes :: Circuit (Df dom (Maybe a)) (Df dom a)
485
485
- catMaybes = Circuit (C.unbundle . fmap go . C.bundle
486
-
+ catMaybes :: C.HiddenClockResetEnable dom => Circuit (Dfs dom (Maybe a)) (Dfs dom a)
Because our function is now stateful, we also need to change the test to:
@@ -551,10 +551,6 @@ instead, this would have mean that the circuit would be stalled for _4_ cycles o
551
551
At this point we're forced to conclude that `forceAckWithLow` did not fix our woes and we should persue a proper fix.
552
552
553
553
## Connecting multiple circuits
554
-
**HEADS UP**: The following instructions only work on GHC 8.6.5. Due to internal GHC changes we can't easily port this to newer versions. This is in the works.
555
-
556
-
-----------------------
557
-
558
554
Check out [tests/Tests/Protocols/Plugin.hs](https://github.com/clash-lang/clash-protocols/blob/main/tests/Tests/Protocols/Plugin.hs) for examples on how to use `Protocols.Plugin` to wire up circuits using a convenient syntax.
559
555
560
556
@@ -563,7 +559,7 @@ Check out [tests/Tests/Protocols/Plugin.hs](https://github.com/clash-lang/clash-
563
559
564
560
# Project goals
565
561
566
-
- Include basic dataflow protocols (e.g., `Df`/`Dfs`) and industry supported ones (e.g., AMBA AXI)
562
+
- Include basic protocols (e.g., `Df`) and industry supported ones (e.g., AMBA AXI)
567
563
- Include lots of basic operators on circuits and its protocols
568
564
- Export a consistent interface across protocols
569
565
- 100% documentation coverage, preferably with lots of examples
@@ -581,7 +577,7 @@ No formal guidelines yet, but feel free to open a PR!
581
577
582
578
-[x] README
583
579
-[x] Add more convenient functions: `fanin`, `roundrobin`, ..
584
-
-[] Make `Dfs` base implementation instead of `Df` (performance / cleanliness)
580
+
-[x] Make `DfLike` base implementation instead of `Df` (performance / cleanliness)
585
581
-[x] Decide what to do with `Protocols.Ack`
586
582
-[ ] Check dead doc links on CI
587
583
-[x] Upstream all changes to `circuit-notation` (where possible)
@@ -591,7 +587,7 @@ No formal guidelines yet, but feel free to open a PR!
591
587
592
588
0.2
593
589
594
-
-[] Make DSL plugin work with GHC 8.10
590
+
-[x] Make DSL plugin work with GHC 8.10 ([github.com/cchalmers/circuit-notation/pull/9](https://github.com/cchalmers/circuit-notation/pull/9))
0 commit comments