:: a -> a package:clash-prelude

Identity function.
id x = x
Force deduplication, i.e. share a function or operator between multiple branches. By default Clash converts
case x of
A -> 3 * y
B -> x * x
to
let f_arg0 = case x of {A -> 3; _ -> x}
f_arg1 = case x of {A -> y; _ -> x}
f_out  = f_arg0 * f_arg1
in  case x of
A -> f_out
B -> f_out
However, it won't do this for:
case x of
A -> 3 + y
B -> x + x
Because according to the internal heuristics the multiplexer introduced for the deduplication are more expensive than the addition. This might not be the case for your particular platform. In these cases you can force Clash to deduplicate by:
case x of
A -> deDup (3 + y)
B -> deDup (x + x)
Do not deduplicate, i.e. keep, an applied function inside a case-alternative; do not try to share the function between multiple branches. By default Clash converts
case x of
A -> f 3 y
B -> f x x
C -> h x
to
let f_arg0 = case x of {A -> 3; _ -> x}
f_arg1 = case x of {A -> y; _ -> x}
f_out  = f f_arg0 f_arg1
in  case x of
A -> f_out
B -> f_out
C -> h x
i.e. it deduplicates functions (and operators such as multiplication) between case-alternatives to save on area. This comes at the cost of multiplexing the arguments for the deduplicated function. There are two reasons you would want to stop Clash from doing this:
  1. The deduplicated function is in the critical path, and the addition of the multiplexers further increased the propagation delay.
  2. Clash's heuristics were off, and the addition of the multiplexers actually made the final circuit larger instead of smaller.
In these cases you want to tell Clash not to deduplicate:
case x of
A -> noDeDup f 3 y
B -> f x x
C -> h x
Where the application of f in the A-alternative is now explicitly not deduplicated, and given that the f in the B-alternative is the only remaining application of f in the case-expression it is also not deduplicated. Note that if the C-alternative also had an application of f, then the applications of f in the B- and C-alternatives would have been deduplicated; i.e. the final circuit would have had two application of f.
Convert XException to ErrorCall This is useful when tracking the source of XException that gets eaten up by pack inside of your circuit; since pack translates XException into undefined bits. So for example if you have some large function f:
f a b = ... pack a ... pack b ...
Where it is basically an error if either a or b ever throws an XException, and so you want that to be reported the moment a or b is used, instead of it being thrown when evaluating the result of f, then do:
{-# LANGUAGE ViewPatterns #-}
f (xToError -> a) (xToError -> b) = ...
Unlike xToErrorCtx, where we have an extra String argument to distinguish one call to xToError to the other, xToError will use the CallStack mechanism to aid the user in distinguishing different call to xToError. We can also use BangPatterns to report the potential XException being thrown by a or b even earlier, i.e. when f is applied:
{-# LANGUAGE ViewPatterns, BangPatterns #-}
f (xToError -> !a) (xToError -> !b) = ...
NB: Fully synthesizable, so doesn't have to be removed before synthesis

Example

>>> :set -XViewPatterns -XDataKinds

>>> import Clash.Sized.BitVector

>>> import GHC.Stack

>>> :{
let f, g, h, h' :: HasCallStack => Bit -> BitVector 8 -> BitVector 8
f = g
g = h
h (xToError -> a) (xToError -> b) = slice d7 d0 (pack a ++# b)
h' a b = slice d7 d0 (pack a ++# b)
:}
>>> h' (errorX "QQ") 3
0b0000_0011

>>> f (errorX "QQ") 3
*** Exception: CallStack (from HasCallStack):
xToError, called at ...
h, called at ...
g, called at ...
f, called at ...
X: QQ
CallStack (from HasCallStack):
errorX, called at ...