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
<p>The <code>fibR</code> function is not synthesizable by the Clash compiler, because, when we take a <em>structural</em> view, <code>fibR</code> describes an infinitely deep structure.</p>
192
-
<p>In principal, descriptions like the above could be synthesized to a circuit, but it would have to be a <em>sequential</em> circuit.
192
+
<p>In principle, descriptions like the above could be synthesized to a circuit, but it would have to be a <em>sequential</em> circuit.
193
193
Where the most general synthesis would then require a stack.
194
194
Such a synthesis approach is also known as <em>behavioral</em> synthesis, something which the Clash compiler simply does not do.
195
195
One reason that Clash does not do this is because it does not fit the paradigm that only functions working on values of type <code>Signal</code> result in sequential circuits, and all other (non higher-order) functions result in combinational circuits.
Where the recursively defined (non-function) value <em>r</em> is synthesized to a feedback loop containing three registers and one adder.</p>
211
211
<p>Note that not all recursively defined values result in a feedback loop.
212
212
An example that uses recursively defined values which does not result in a feedback loop is the following function that performs one iteration of bubble sort:</p>
sorted = zipWith compareSwapL (lazyV lefts) rights
217
+
sorted = zipWith compareAndSwap (lazyV lefts) rights
218
+
219
+
compareAndSwap a b = if a < b then (a,b) else (b,a)
218
220
</code></pre>
219
-
<p>Where we can clearly see that <code>lefts</code> and <code>sorted</code> are defined in terms of each other. Also the above <code>sortV</code> function <em>is</em> synthesizable.</p>
221
+
<p>Where we can clearly see that <code>lefts</code> and <code>sorted</code> are defined in terms of each other.
222
+
Also the above <code>sortV</code> function <em>is</em> synthesizable.</p>
While this is trivial for values of the elementary types, sum types, and product types, putting a fixed upper bound on recursive types is not (always) feasible.
246
249
This means that the ubiquitous list type is unsupported!
247
250
The only recursive types that are currently supported by the Clash compiler is the <code>Vec</code>tor and <code>RTree</code> types, for which the compiler has hard-coded knowledge.</p>
248
-
<p>For "easy" <code>Vec</code>tor literals you should use Template Haskell splices and the <code>listToVecTH</code><em>meta</em>-function that as we have seen earlier in this tutorial.</p>
251
+
<p>For "easy" <code>Vec</code>tor literals you should use Template Haskell splices and the <code>listToVecTH</code><em>meta</em>-function.</p>
249
252
</li>
250
253
<li>
251
254
<p><strong>GADTs</strong></p>
252
-
<p>Clash has experimental support for GADTs. Similar to recursive types, Clash can't determine bit-sizes of GADTs.
255
+
<p>Clash has experimental support for GADTs.
256
+
Similar to recursive types, Clash cannot determine bit-sizes of GADTs.
253
257
Notable exceptions to this rule are <code>Vec</code> and <code>RTree</code>.
254
258
You can still use your own GADTs, as long as they can be removed through static analysis.
255
259
For example, the following case will be optimized away and is therefore fine to use:</p>
<p>which underlie <code>Float</code>'s <code>Num</code> instance, must be implemented as purely combinational circuits according to their type.
275
-
Remember, sequential circuits operate on values of type "<code>Signal dom a</code>".</p>
279
+
Remember, sequential circuits operate on values of type <code>Signal dom a</code>.</p>
276
280
</li>
277
281
</ol>
278
282
<p>Although it is possible to implement purely combinational (not pipelined) arithmetic circuits for floating point data types, the circuit would be unreasonable slow.
279
-
So, without synthesis possibilities for the basic arithmetic operations, there is no point in supporting the floating point data types.</p>
283
+
So, without synthesis possibilities for the basic arithmetic operations, there is no point in supporting the floating point data types.</p>
<p>There are several aspects of which you should take note:</p>
299
303
<ul>
300
304
<li>
301
-
<p>'Int' and 'Word' are represented by the same number of bits as is native for the architecture of the computer on which the Clash compiler is executed.
302
-
This means that if you are working on a 64-bit machine, 'Int' and 'Word' will be 64-bit.
305
+
<p><code>Int</code> and <code>Word</code> are represented by the same number of bits as is native for the architecture of the computer on which the Clash compiler is executed.
306
+
This means that if you are working on a 64-bit machine, <code>Int</code> and <code>Word</code> will be 64-bit.
303
307
This might be problematic when you are working in a team, and one designer has a 32-bit machine, and the other has a 64-bit machine.
304
308
In general, you should be avoiding 'Int' in such cases, but as a band-aid solution, you can force the Clash compiler to use a specific bit-width for <code>Int</code> and <code>Word</code> using the <code>-fclash-intwidth=N</code> flag, where <em>N</em> must either be <em>32</em> or <em>64</em>.</p>
305
309
</li>
306
310
<li>
307
311
<p>When you use the <code>-fclash-intwidth=32</code> flag on a <em>64-bit</em> machine, the 'Word64' and 'Int64' types <em>cannot</em> be translated. This restriction does <em>not</em> apply to the other three combinations of <code>-fclash-intwidth</code> flag and machine type.</p>
308
312
</li>
309
313
<li>
310
-
<p>The translation of 'Integer' is not meaning-preserving. 'Integer' in Haskell is an arbitrary precision integer, something that cannot be represented in a statically known number of bits.
314
+
<p>The translation of 'Integer' is not meaning-preserving.
315
+
'Integer' in Haskell is an arbitrary precision integer, something that cannot be represented in a statically known number of bits.
311
316
In the Clash compiler, we chose to represent 'Integer' by the same number of bits as we do for <code>Int</code> and <code>Word</code>.
312
317
As you have read in a previous bullet point, this number of bits is either 32 or 64, depending on the architecture of the machine the Clash compiler is running on, or the setting of the <code>-fclash-intwidth</code> flag.</p>
313
-
<p>Consequently, you should use <code>Integer</code> with due diligence; be especially careful when using <code>fromIntegral</code> as it does a conversion via 'Integer'. For example:</p>
318
+
<p>Consequently, you should use <code>Integer</code> with due diligence; be especially careful when using <code>fromIntegral</code> as it does a conversion via 'Integer'.
319
+
For example:</p>
314
320
<pre><codeclass="language-haskell">signedToUnsigned :: Signed 128 -> Unsigned 128
315
321
signedToUnsigned = fromIntegral
316
322
</code></pre>
317
-
<p>can either lose the top 64 or 96 bits depending on whether 'Integer' is represented by 64 or 32 bits.
318
-
Instead, when doing such conversions, you should use 'bitCoerce':</p>
323
+
<p>can either lose the top 64 or 96 bits depending on whether <code>Integer</code> is represented by 64 or 32 bits.
324
+
Instead, when doing such conversions, you should use <code>bitCoerce</code>:</p>
319
325
<pre><codeclass="language-haskell">signedToUnsigned :: Signed 128 -> Unsigned 128
<p>The <code>fibR</code> function is not synthesizable by the Clash compiler, because, when we take a <em>structural</em> view, <code>fibR</code> describes an infinitely deep structure.</p>
1182
-
<p>In principal, descriptions like the above could be synthesized to a circuit, but it would have to be a <em>sequential</em> circuit.
1182
+
<p>In principle, descriptions like the above could be synthesized to a circuit, but it would have to be a <em>sequential</em> circuit.
1183
1183
Where the most general synthesis would then require a stack.
1184
1184
Such a synthesis approach is also known as <em>behavioral</em> synthesis, something which the Clash compiler simply does not do.
1185
1185
One reason that Clash does not do this is because it does not fit the paradigm that only functions working on values of type <code>Signal</code> result in sequential circuits, and all other (non higher-order) functions result in combinational circuits.
Where the recursively defined (non-function) value <em>r</em> is synthesized to a feedback loop containing three registers and one adder.</p>
1201
1201
<p>Note that not all recursively defined values result in a feedback loop.
1202
1202
An example that uses recursively defined values which does not result in a feedback loop is the following function that performs one iteration of bubble sort:</p>
sorted = zipWith compareSwapL (lazyV lefts) rights
1207
+
sorted = zipWith compareAndSwap (lazyV lefts) rights
1208
+
1209
+
compareAndSwap a b = if a < b then (a,b) else (b,a)
1208
1210
</code></pre>
1209
-
<p>Where we can clearly see that <code>lefts</code> and <code>sorted</code> are defined in terms of each other. Also the above <code>sortV</code> function <em>is</em> synthesizable.</p>
1211
+
<p>Where we can clearly see that <code>lefts</code> and <code>sorted</code> are defined in terms of each other.
1212
+
Also the above <code>sortV</code> function <em>is</em> synthesizable.</p>
While this is trivial for values of the elementary types, sum types, and product types, putting a fixed upper bound on recursive types is not (always) feasible.
1236
1239
This means that the ubiquitous list type is unsupported!
1237
1240
The only recursive types that are currently supported by the Clash compiler is the <code>Vec</code>tor and <code>RTree</code> types, for which the compiler has hard-coded knowledge.</p>
1238
-
<p>For "easy" <code>Vec</code>tor literals you should use Template Haskell splices and the <code>listToVecTH</code><em>meta</em>-function that as we have seen earlier in this tutorial.</p>
1241
+
<p>For "easy" <code>Vec</code>tor literals you should use Template Haskell splices and the <code>listToVecTH</code><em>meta</em>-function.</p>
1239
1242
</li>
1240
1243
<li>
1241
1244
<p><strong>GADTs</strong></p>
1242
-
<p>Clash has experimental support for GADTs. Similar to recursive types, Clash can't determine bit-sizes of GADTs.
1245
+
<p>Clash has experimental support for GADTs.
1246
+
Similar to recursive types, Clash cannot determine bit-sizes of GADTs.
1243
1247
Notable exceptions to this rule are <code>Vec</code> and <code>RTree</code>.
1244
1248
You can still use your own GADTs, as long as they can be removed through static analysis.
1245
1249
For example, the following case will be optimized away and is therefore fine to use:</p>
<p>which underlie <code>Float</code>'s <code>Num</code> instance, must be implemented as purely combinational circuits according to their type.
1265
-
Remember, sequential circuits operate on values of type "<code>Signal dom a</code>".</p>
1269
+
Remember, sequential circuits operate on values of type <code>Signal dom a</code>.</p>
1266
1270
</li>
1267
1271
</ol>
1268
1272
<p>Although it is possible to implement purely combinational (not pipelined) arithmetic circuits for floating point data types, the circuit would be unreasonable slow.
1269
-
So, without synthesis possibilities for the basic arithmetic operations, there is no point in supporting the floating point data types.</p>
1273
+
So, without synthesis possibilities for the basic arithmetic operations, there is no point in supporting the floating point data types.</p>
<p>There are several aspects of which you should take note:</p>
1289
1293
<ul>
1290
1294
<li>
1291
-
<p>'Int' and 'Word' are represented by the same number of bits as is native for the architecture of the computer on which the Clash compiler is executed.
1292
-
This means that if you are working on a 64-bit machine, 'Int' and 'Word' will be 64-bit.
1295
+
<p><code>Int</code> and <code>Word</code> are represented by the same number of bits as is native for the architecture of the computer on which the Clash compiler is executed.
1296
+
This means that if you are working on a 64-bit machine, <code>Int</code> and <code>Word</code> will be 64-bit.
1293
1297
This might be problematic when you are working in a team, and one designer has a 32-bit machine, and the other has a 64-bit machine.
1294
1298
In general, you should be avoiding 'Int' in such cases, but as a band-aid solution, you can force the Clash compiler to use a specific bit-width for <code>Int</code> and <code>Word</code> using the <code>-fclash-intwidth=N</code> flag, where <em>N</em> must either be <em>32</em> or <em>64</em>.</p>
1295
1299
</li>
1296
1300
<li>
1297
1301
<p>When you use the <code>-fclash-intwidth=32</code> flag on a <em>64-bit</em> machine, the 'Word64' and 'Int64' types <em>cannot</em> be translated. This restriction does <em>not</em> apply to the other three combinations of <code>-fclash-intwidth</code> flag and machine type.</p>
1298
1302
</li>
1299
1303
<li>
1300
-
<p>The translation of 'Integer' is not meaning-preserving. 'Integer' in Haskell is an arbitrary precision integer, something that cannot be represented in a statically known number of bits.
1304
+
<p>The translation of 'Integer' is not meaning-preserving.
1305
+
'Integer' in Haskell is an arbitrary precision integer, something that cannot be represented in a statically known number of bits.
1301
1306
In the Clash compiler, we chose to represent 'Integer' by the same number of bits as we do for <code>Int</code> and <code>Word</code>.
1302
1307
As you have read in a previous bullet point, this number of bits is either 32 or 64, depending on the architecture of the machine the Clash compiler is running on, or the setting of the <code>-fclash-intwidth</code> flag.</p>
1303
-
<p>Consequently, you should use <code>Integer</code> with due diligence; be especially careful when using <code>fromIntegral</code> as it does a conversion via 'Integer'. For example:</p>
1308
+
<p>Consequently, you should use <code>Integer</code> with due diligence; be especially careful when using <code>fromIntegral</code> as it does a conversion via 'Integer'.
1309
+
For example:</p>
1304
1310
<pre><codeclass="language-haskell">signedToUnsigned :: Signed 128 -> Unsigned 128
1305
1311
signedToUnsigned = fromIntegral
1306
1312
</code></pre>
1307
-
<p>can either lose the top 64 or 96 bits depending on whether 'Integer' is represented by 64 or 32 bits.
1308
-
Instead, when doing such conversions, you should use 'bitCoerce':</p>
1313
+
<p>can either lose the top 64 or 96 bits depending on whether <code>Integer</code> is represented by 64 or 32 bits.
1314
+
Instead, when doing such conversions, you should use <code>bitCoerce</code>:</p>
1309
1315
<pre><codeclass="language-haskell">signedToUnsigned :: Signed 128 -> Unsigned 128
0 commit comments