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 ...