clash-lang / clash-prelude

CLaSH prelude library containing datatypes and functions for circuit design
http://www.clash-lang.org/
Other
31 stars 27 forks source link

moore' can't be synthesized? #53

Open dented42 opened 8 years ago

dented42 commented 8 years ago

When I try to compile a design that uses a moore machine, I get the following error:

Loading dependencies took 17.130628s

<no location info>:
    CLaSH Error:
CLaSH.Normalize(180): Callgraph after normalisation contains following recursive cycles: [[CLaSH.Prelude.Moore.$wmoore'_s1138]]
make: *** [out/gen/vhdl/*.vhdl] Error 1

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.

christiaanb commented 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:

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

dented42 commented 8 years ago

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))))
dented42 commented 8 years ago

And yes, I am using 0.6.17

christiaanb commented 8 years ago

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:

So yeah, instead of just reporting that moore' remains recursive, CLaSH should've told you that this is due to the DecodeST GADT