Skip to content

Commit ab4c2fe

Browse files
committed
Add troubleshooting guide from Clash.Tutorial
1 parent fd8c311 commit ab4c2fe

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

compiler-user-guide/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
- [Flags](./developing-hardware/flags.md)
1515
- [Controlling HDL generation](./developing-hardware/annotations.md)
1616
- [User-defined primitives](./developing-hardware/primitives.md)
17+
- [Troubleshooting](./developing-hardware/troubleshooting.md)
1718
- [Limitations of the compiler](./developing-hardware/limitations.md)
1819
- [Hacking on Clash](./hacking-on-clash/index.md)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Troubleshooting
2+
3+
A list of often encountered errors and their solutions:
4+
5+
* __Type error: Couldn't match expected type `Signal dom (a,b)` with actual type `(Signal dom a, Signal dom b)`__:
6+
7+
Signals of product types and product types of signals are __isomorphic__ due to synchronisity principle, but are not (structurally) equal.
8+
Tuples are a product type. Use the `bundle` function to convert from a product type to the signal type.
9+
So if your code which gives the error looks like:
10+
11+
``` haskell
12+
... = f a b (c,d)
13+
```
14+
15+
add the `bundle` function like so:
16+
17+
``` haskell
18+
... = f a b (bundle (c,d))
19+
```
20+
21+
Product types supported by `bundle` are:
22+
23+
* All tuples up to and including 62-tuples (GHC limit)
24+
* The `Vec`tor type
25+
26+
* __Type error: Couldn't match expected type `(Signal dom a, Signal dom b)` with actual type `Signal dom (a,b)`__:
27+
28+
Product types of signals and signals of product types are __isomorphic__ due to synchronicity principle, but are not (structurally) equal.
29+
Tuples are a product type. Use the `unbundle` function to convert from a signal type to the product type.
30+
So if your code which gives the error looks like:
31+
32+
``` haskell
33+
(c,d) = f a b
34+
```
35+
36+
add the `unbundle` function like so:
37+
38+
``` haskell
39+
(c,d) = unbundle (f a b)
40+
```
41+
42+
Product types supported by `unbundle` are:
43+
44+
* All tuples up to and including 62-tuples (GHC limit)
45+
* The `Vec`tor type
46+
47+
* __Clash.Netlist(..): Not in normal form: \<REASON\>: \<EXPR\>__:
48+
49+
A function could not be transformed into the expected normal form.
50+
This usually means one of the following:
51+
52+
* The `topEntity` has higher-order arguments, or a higher-order result.
53+
* You are using types which cannot be represented in hardware.
54+
55+
The solution for all the above listed reasons is quite simple: remove them.
56+
That is, make sure that the `topEntity` is completely monomorphic and first-order.
57+
Also remove any variables and constants/literals that have a non-representable type; see [Limitations of Clash](limitations.md) to find out which types are not representable.
58+
59+
* __Clash.Normalize(..): Clash can only normalize monomorphic functions, but this is polymorphic__:
60+
61+
If this happens for a `topEntity` or something with a `Synthesize` annotation, add a monomorphic type signature.
62+
Non topEntites should be type-specialized by clash automatically, if not please report this as a bug.
63+
But adding a monomorphic type signature should still help (when possible).
64+
65+
* __Clash.Normalize(..): Expr belonging to bndr: \<FUNCTION\> remains recursive after normalization__:
66+
67+
* If you actually wrote a recursive function, rewrite it to a non-recursive one using e.g. one of the higher-order functions in `Clash.Sized.Vector`
68+
69+
* You defined a recursively defined value, but left it polymorphic:
70+
71+
``` haskell
72+
topEntity x y = acc
73+
where
74+
acc = register 3 (acc + x * y)
75+
```
76+
77+
The above function, works for any number-like type.
78+
This means that `acc` is a recursively defined __polymorphic__ value.
79+
Adding a monomorphic type annotation makes the error go away:
80+
81+
``` haskell
82+
topEntity
83+
:: SystemClockResetEnable
84+
=> Signal System (Signed 8)
85+
-> Signal System (Signed 8)
86+
-> Signal System (Signed 8)
87+
topEntity x y = acc
88+
where
89+
acc = register 3 (acc + x * y)
90+
```
91+
92+
* __Clash.Normalize.Transformations(..): InlineNonRep: \<FUNCTION\> already inlined 100 times in:\<FUNCTION\>, \<TYPE\>__:
93+
94+
You left the `topEntity` function polymorphic or higher-order: use `:i topEntity` to check if the type is indeed polymorphic or higher-order.
95+
If it is, add a monomorphic type signature, and/or supply higher-order arguments.
96+
97+
* __<*** Exception: <\<loop\>> or "blinking cursor"__
98+
99+
You are using value-recursion, but one of the `Vec`tor functions that you are using is too *strict* in one of the recursive arguments. For example:
100+
101+
``` haskell
102+
-- Bubble sort for 1 iteration
103+
sortV xs = map fst sorted :< (snd (last sorted))
104+
where
105+
lefts = head xs :> map snd (init sorted)
106+
rights = tail xs
107+
sorted = zipWith compareSwapL lefts rights
108+
109+
-- Compare and swap
110+
compareSwapL a b = if a < b then (a,b) else (b,a)
111+
```
112+
113+
Will not terminate because `zipWith` is too strict in its second argument.
114+
115+
In this case, adding `lazyV` on `zipWith`s second argument:
116+
117+
``` haskell
118+
sortVL xs = map fst sorted :< (snd (last sorted))
119+
where
120+
lefts = head xs :> map snd (init sorted)
121+
rights = tail xs
122+
sorted = zipWith compareSwapL (lazyV lefts) rights
123+
```
124+
125+
Results in a successful computation:
126+
127+
```
128+
clashi> sortVL (4 :> 1 :> 2 :> 3 :> Nil)
129+
1 :> 2 :> 3 :> 4 :> Nil
130+
```

0 commit comments

Comments
 (0)