Skip to content

Expressions remains recursive after normalization #5

Description

@TristanCacqueray

Hello,

when trying to build tinybasic with ghc-9.6.7 and clash-1.8.4, verilog synthesis fails with the following error:

$ clashi src/intel8080/video-board.hs -isrc
Clashi, version 1.8.4 (using clash-lib, version 1.8.4):
clashi> :verilog
Clash: Compiling Main.topEntity
Clash.Normalize(187): Expr belonging to bndr: c$Data.Monoid.$fMonoidAp_$cmconcat_go1[393088] (:: GHC.Types.List[3674937295934324788]
  (Data.Monoid.Ap[8214565720323893074]
     (GHC.Prim.TYPE[3674937295934324918]
        (GHC.Types.BoxedRep[3891110078048108766]
           GHC.Types.Lifted[3891110078048108808]))
     (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
     (GHC.Maybe.Maybe[3674937295934324792]
        (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
           8)))
-> Data.Monoid.Ap[8214565720323893074]
     (GHC.Prim.TYPE[3674937295934324918]
        (GHC.Types.BoxedRep[3891110078048108766]
           GHC.Types.Lifted[3891110078048108808]))
     (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
     (GHC.Maybe.Maybe[3674937295934324792]
        (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
           8))) remains recursive after normalization:
λ(ds[8214565720324003356] :: GHC.Types.List[3674937295934324788]
                               (Data.Monoid.Ap[8214565720323893074]
                                  (GHC.Prim.TYPE[3674937295934324918]
                                     (GHC.Types.BoxedRep[3891110078048108766]
                                        GHC.Types.Lifted[3891110078048108808]))
                                  (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                  (GHC.Maybe.Maybe[3674937295934324792]
                                     (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                        8)))) ->
letrec
  result[397188] :: GHC.Maybe.Maybe[3674937295934324792]
                      (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                         8)
  = <prefixName>"liftA2"
  <prefixName>"$fApplicativeSignal"
  <prefixName>"$fApplicativeSignal_$cliftA2"
  <prefixName>"<>"
  <prefixName>"muxA_v1"
  <prefixName>"$fMonoidAlt"
  <prefixName>"$fSemigroupAlt"
  <prefixName>"<|>"
  <prefixName>"$fAlternativeMaybe"
  <prefixName>"$fAlternativeMaybe_$c<|>"
  case y[8214565720324003359][LocalId] of
    GHC.Maybe.Nothing[3891110078048108565]  ->
      eta2[8214565720324020536][LocalId]
    GHC.Maybe.Just[3891110078048108568]
      (ipv[8214565720324020882] :: Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                     8) ->
      y[8214565720324003359][LocalId]
  y[8214565720324003359] :: Data.Monoid.Ap[8214565720323893074]
                              (GHC.Prim.TYPE[3674937295934324918]
                                 (GHC.Types.BoxedRep[3891110078048108766]
                                    GHC.Types.Lifted[3891110078048108808]))
                              (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                              (GHC.Maybe.Maybe[3674937295934324792]
                                 (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                    8))
  = case ds[8214565720324003356][LocalId] of
      GHC.Types.:[3891110078048108550]
        (c$sel[397191] :: Data.Monoid.Ap[8214565720323893074]
                            (GHC.Prim.TYPE[3674937295934324918]
                               (GHC.Types.BoxedRep[3891110078048108766]
                                  GHC.Types.Lifted[3891110078048108808]))
                            (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                            (GHC.Maybe.Maybe[3674937295934324792]
                               (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                  8)))
          (c$wild[397190] :: GHC.Types.List[3674937295934324788]
                               (Data.Monoid.Ap[8214565720323893074]
                                  (GHC.Prim.TYPE[3674937295934324918]
                                     (GHC.Types.BoxedRep[3891110078048108766]
                                        GHC.Types.Lifted[3891110078048108808]))
                                  (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                  (GHC.Maybe.Maybe[3674937295934324792]
                                     (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                        8)))) ->
        c$sel[397191][LocalId]
  ys[8214565720324003360] :: GHC.Types.List[3674937295934324788]
                               (Data.Monoid.Ap[8214565720323893074]
                                  (GHC.Prim.TYPE[3674937295934324918]
                                     (GHC.Types.BoxedRep[3891110078048108766]
                                        GHC.Types.Lifted[3891110078048108808]))
                                  (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                  (GHC.Maybe.Maybe[3674937295934324792]
                                     (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                        8)))
  = case ds[8214565720324003356][LocalId] of
      GHC.Types.:[3891110078048108550]
        (c$wild[397192] :: Data.Monoid.Ap[8214565720323893074]
                             (GHC.Prim.TYPE[3674937295934324918]
                                (GHC.Types.BoxedRep[3891110078048108766]
                                   GHC.Types.Lifted[3891110078048108808]))
                             (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                             (GHC.Maybe.Maybe[3674937295934324792]
                                (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                   8)))
          (c$sel[397194] :: GHC.Types.List[3674937295934324788]
                              (Data.Monoid.Ap[8214565720323893074]
                                 (GHC.Prim.TYPE[3674937295934324918]
                                    (GHC.Types.BoxedRep[3891110078048108766]
                                       GHC.Types.Lifted[3891110078048108808]))
                                 (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                 (GHC.Maybe.Maybe[3674937295934324792]
                                    (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                       8)))) ->
        c$sel[397194][LocalId]
  eta2[8214565720324020536] :: Data.Monoid.Ap[8214565720323893074]
                                 (GHC.Prim.TYPE[3674937295934324918]
                                    (GHC.Types.BoxedRep[3891110078048108766]
                                       GHC.Types.Lifted[3891110078048108808]))
                                 (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                 (GHC.Maybe.Maybe[3674937295934324792]
                                    (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                       8))
  = c$Data.Monoid.$fMonoidAp_$cmconcat_go1[393088][GlobalId]
      ys[8214565720324003360][LocalId]
  result[397195] :: Data.Monoid.Ap[8214565720323893074]
                      (GHC.Prim.TYPE[3674937295934324918]
                         (GHC.Types.BoxedRep[3891110078048108766]
                            GHC.Types.Lifted[3891110078048108808]))
                      (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                      (GHC.Maybe.Maybe[3674937295934324792]
                         (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                            8))
  = case ds[8214565720324003356][LocalId] of
      GHC.Types.[][3891110078048108574]  ->
        <prefixName>"pure"
        <prefixName>"$fApplicativeSignal"
        <prefixName>"mempty"
        <prefixName>"muxA_v1"
        <prefixName>"$fMonoidAlt"
        <prefixName>"empty"
        <prefixName>"$fAlternativeMaybe"
          GHC.Maybe.Nothing[3891110078048108565]
          @(Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
              8)
      GHC.Types.:[3891110078048108550]
        (y[8214565720324003359] :: Data.Monoid.Ap[8214565720323893074]
                                     (GHC.Prim.TYPE[3674937295934324918]
                                        (GHC.Types.BoxedRep[3891110078048108766]
                                           GHC.Types.Lifted[3891110078048108808]))
                                     (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                     (GHC.Maybe.Maybe[3674937295934324792]
                                        (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                           8)))
          (ys[8214565720324003360] :: GHC.Types.List[3674937295934324788]
                                        (Data.Monoid.Ap[8214565720323893074]
                                           (GHC.Prim.TYPE[3674937295934324918]
                                              (GHC.Types.BoxedRep[3891110078048108766]
                                                 GHC.Types.Lifted[3891110078048108808]))
                                           (Clash.Signal.Internal.Signal[8214565720323892722] "Dom25")
                                           (GHC.Maybe.Maybe[3674937295934324792]
                                              (Clash.Sized.Internal.BitVector.BitVector[8214565720323892754]
                                                 8)))) ->
        result[397188][LocalId]
in result[397195][LocalId]

It looks like the issue comes from RetroClash.Utils.shifterL, and using this implementation fixes the recursion:

shifterL' ::
    (BitPack a, HiddenClockResetEnable dom) =>
    Signal dom (Maybe a) ->
    Signal dom Bool ->
    Signal dom Bit
shifterL' load tick = msb <$> next
  where
    r = register 0 next

    initial = fmap pack <$> load
    shifted = (`shiftL` 1) <$> r
    next = muxA (initial :> enable tick shifted :> Nil) .<|. r

… that way:

diff --git a/src/Hardware/TinyBASIC/Video.hs b/src/Hardware/TinyBASIC/Video.hs
index b20e59c..2f6077a 100644
--- a/src/Hardware/TinyBASIC/Video.hs
+++ b/src/Hardware/TinyBASIC/Video.hs
@@ -90,7 +90,7 @@ video (fromSignal -> cursor) (fromSignal -> w) = (frameEnd, delayVGA vgaSync rgb
: 
 
     glyphLoad = enable (delayI False newChar) $ fontRom charLoad (fromMaybe 0 <$> delayI Nothing (fromSignal glyphY))
     newCol = delayI False $ fromSignal $ changed Nothing glyphX
-    pixel = enable (delayI False visible) $ liftD2 shifterL glyphLoad newCol
+    pixel = enable (delayI False visible) $ liftD2 shifterL' glyphLoad newCol

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions