Open dented42 opened 8 years ago
I guess you mean that the moore'
function cannot be synthesized? Also, you are using clash 0.6.17, correct?
Now, moore'
should definitely be synthesizable. However, CLaSH cannot synthesize recursive functions. Now, assuming you didn't actually write a recursive function, there are several reasons you might be getting the above error:
moore'
, https://github.com/clash-lang/clash-prelude/blob/master/src/CLaSH/Prelude/Moore.hs#L167, is turned into a recursive function by GHC, and CLaSH fails to transform it back to a recursive where-clause. (Yes, GHC actually does that, and yes, CLaSH has a transformation to does the inverse of what GHC does).moore'
is recursive.To figure out what's going on, could you run clash
using the -clash-debug DebugFinal
flag, and give me the entire function definition after the lines: CLaSH.Prelude.Moore.$wmoore'_s1138 before normalization:
and CLaSH.Prelude.Moore.$wmoore'_s1138 after normalization:
.
I think you mean this?
CLaSH.Normalize(147): Expr belonging to bndr: CLaSH.Prelude.Moore.$wmoore'_s1138 (:: CLaSH.Signal.Internal.Signal'
(CLaSH.Signal.Internal.Clk io 2000)
(GHC.Tuple.(,) GHC.Types.Bool GHC.Types.Bool)
-> CLaSH.Signal.Internal.Signal'
(CLaSH.Signal.Internal.Clk io 2000)
(GHC.Tuple.(,)
GHC.Types.Bool (SerialDecoder.DecodeST 8 GHC.Types.Bool))) has a non-representable return type. Not normalising:
λ(w3 :: CLaSH.Signal.Internal.Signal'
(CLaSH.Signal.Internal.Clk io 2000)
(GHC.Tuple.(,) GHC.Types.Bool GHC.Types.Bool)) ->
CLaSH.Signal.Internal.register#
@(CLaSH.Signal.Internal.Clk io 2000)
@(GHC.Tuple.(,)
GHC.Types.Bool (SerialDecoder.DecodeST 8 GHC.Types.Bool))
(Control.Exception.Base.absentError
@(CLaSH.Signal.Internal.SClock (CLaSH.Signal.Internal.Clk io 2000))
"w_s1Jjd SClock clk")
(GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.Halted
@8
@GHC.Types.Bool
8))
(case (CLaSH.Prelude.Moore.$wmoore'_s1138
w3) of
GHC.Tuple.(,)
(ds2 :: GHC.Types.Bool)
(x :: SerialDecoder.DecodeST 8 GHC.Types.Bool) ->
case ds2 of
GHC.Types.False ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.True
x
GHC.Types.True ->
case w3 of
GHC.Tuple.(,)
(ds3 :: GHC.Types.Bool)
(ds4 :: GHC.Types.Bool) ->
case ds3 of
GHC.Types.False ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.Halted
@8
@GHC.Types.Bool
8)
GHC.Types.True ->
case x of
SerialDecoder.Halted
($dKnownNat :: GHC.TypeLits.KnownNat 8) ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.ReadShift
@8
@GHC.Types.Bool
$dKnownNat
(GHC.Base.Nothing
@(CLaSH.Sized.Vector.Vec 8 GHC.Types.Bool)))
SerialDecoder.ReadShift
($dKnownNat :: GHC.TypeLits.KnownNat 8)
(ov :: GHC.Base.Maybe (CLaSH.Sized.Vector.Vec 8 GHC.Types.Bool)) ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.RcvBit
@8
@GHC.Types.Bool
@GHC.Integer.Type.Integer
$dKnownNat
GHC.Enum.$fEnumInteger1912624553
$dKnownNat
(CLaSH.Sized.Vector.replicate
@8
@GHC.Types.Bool
(CLaSH.Promoted.Nat.SNat
@8
$dKnownNat
(Data.Proxy.Proxy
@GHC.TypeLits.Nat
@8))
(GHC.Err.undefined
@GHC.Types.Bool))
ov)
SerialDecoder.RcvBit idx
($dKnownNat :: GHC.TypeLits.KnownNat 8)
($dEnum :: GHC.Enum.Enum idx)
(idx1 :: idx)
(v :: CLaSH.Sized.Vector.Vec 8 GHC.Types.Bool)
(ds5 :: GHC.Base.Maybe
(CLaSH.Sized.Vector.Vec 8 GHC.Types.Bool)) ->
case case $dEnum of
GHC.Enum.D:Enum
(wild6 :: idx -> idx)
(wild5 :: idx -> idx)
(wild4 :: GHC.Types.Int -> idx)
(sel :: idx -> GHC.Types.Int)
(wild3 :: idx -> GHC.Types.[] idx)
(wild2 :: idx -> idx -> GHC.Types.[] idx)
(wild1 :: idx -> idx -> GHC.Types.[] idx)
(wild :: idx -> idx -> idx -> GHC.Types.[] idx) ->
sel
idx1 of
GHC.Types.I#
(y :: GHC.Prim.Int#) ->
case y of
_ ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.RcvBit
@8
@GHC.Types.Bool
@idx
$dKnownNat
$dEnum
(GHC.Enum.pred1912603236
@idx
$dEnum
idx1)
(CLaSH.Sized.Vector.replace_int
@8
@GHC.Types.Bool
$dKnownNat
v
(case $dEnum of
GHC.Enum.D:Enum
(wild6 :: idx -> idx)
(wild5 :: idx -> idx)
(wild4 :: GHC.Types.Int -> idx)
(sel :: idx -> GHC.Types.Int)
(wild3 :: idx -> GHC.Types.[] idx)
(wild2 :: idx -> idx -> GHC.Types.[] idx)
(wild1 :: idx -> idx -> GHC.Types.[] idx)
(wild :: idx -> idx -> idx -> GHC.Types.[] idx) ->
sel
idx1)
ds4)
ds5)
0 ->
GHC.Tuple.(,)
@GHC.Types.Bool
@(SerialDecoder.DecodeST 8 GHC.Types.Bool)
GHC.Types.False
(SerialDecoder.ReadShift
@8
@GHC.Types.Bool
$dKnownNat
(GHC.Base.Just
@(CLaSH.Sized.Vector.Vec 8 GHC.Types.Bool)
(CLaSH.Sized.Vector.replace_int
@8
@GHC.Types.Bool
$dKnownNat
v
(GHC.Types.I#
0)
ds4))))
And yes, I am using 0.6.17
The "problem" is the DecodeST
GADT, specifically, pattern matching on GADTs is not supported: http://hackage.haskell.org/package/clash-prelude-0.10.7/docs/CLaSH-Tutorial.html#g:19
So here's what's happening:
mooreTransition
, which is returning a GADTmooreTransition
because it knows it will never be able to get rid of the GADT result.moore'
, because a function used by moore'
is non-synthesizable.moore'
does not undergo the normalisation process, the recursive where-clause turned to recursive function is not transformed back to a recursive where-clause.moore'
.So yeah, instead of just reporting that moore'
remains recursive, CLaSH should've told you that this is due to the DecodeST
GADT
When I try to compile a design that uses a moore machine, I get the following error:
It seems to indicate that moore machines can't be synthesized? but I'm wondering if perhaps optimizations are hiding the fact that the problem is in my program. If that's the case then I suppose this is really a compiler bug because it's failing to leave an appropriate error message.