Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synthesising BitPack instances for type with phantom parameter fails #1242

Closed
alastairbarnett opened this issue Mar 23, 2020 · 1 comment · Fixed by #1243
Closed

Synthesising BitPack instances for type with phantom parameter fails #1242

alastairbarnett opened this issue Mar 23, 2020 · 1 comment · Fixed by #1243
Labels

Comments

@alastairbarnett
Copy link

alastairbarnett commented Mar 23, 2020

I've been having trouble synthesising the following code (in Clash 1.2.0) which uses types which include phantom type parameters being included in a record.

{-# LANGUAGE StandaloneDeriving    #-}
{-# LANGUAGE UndecidableInstances  #-}
module Project where

import           Clash.Prelude
import           Control.DeepSeq   (NFData)
import           GHC.Generics      (Generic)

data RepKind = AppRep | WireRep
  deriving (Generic, Show, Eq, NFData, NFDataX)

newtype U16 (t :: RepKind) = U16 (Unsigned 16)

deriving instance Generic (U16 a)
deriving instance Eq (U16 a)
deriving instance Show (U16 a)
deriving instance NFData (U16 a)
deriving instance NFDataX (U16 a)
deriving instance BitPack (U16 'AppRep)

class WireApp w a where
    toWire :: a -> w
    toApp :: w -> a

instance WireApp (U16 'WireRep) (U16 'AppRep) where
    toWire v = case v of U16 x -> U16 x
    toApp v = case v of U16 x -> U16 x

instance (BitPack (t 'AppRep), WireApp (t 'WireRep)  (t 'AppRep)) => BitPack (t 'WireRep) where
  type BitSize (t 'WireRep) = BitSize (t 'AppRep)
  pack x = bv
    where
        bv :: BitVector (BitSize (t 'WireRep))
        bv = pack app
        app :: t 'AppRep
        app = toApp $ x
  unpack x = toWire app
    where
        app :: t 'AppRep
        app = unpack x

data Record
  = Record
  { f1 :: U16 'WireRep
  , f2 :: U16 'WireRep
  } deriving (Generic, NFData, Show, Eq, BitPack, NFDataX)

topEntity :: Signal System Bool -> Signal System Bool
topEntity _ = pure (unpack 0 == Record (U16 0) (U16 0))

When I attempt to synthesise this code to VHDL I am getting the below error.
When I remove the --vhdl flag, compilation completes fine.
Is there any known reason for this?

$ stack exec clash -- -XBinaryLiterals -XDataKinds -XDeriveAnyClass -XDeriveGeneric -XDeriveLift -XDuplicateRecordFields -XFlexibleContexts -XFlexibl
eInstances -XFunctionalDependencies -XLambdaCase -XMagicHash -XMultiParamTypeClasses -XMultiWayIf -XScopedTypeVariables -XTemplateHaskell -XTypeApp
lications -XTypeFamilies -XTypeOperators -XNoImplicitPrelude -XTypeSynonymInstances -XTupleSections -fconstraint-solver-iterations=100 -fplugin=GHC
.TypeLits.KnownNat.Solver -fplugin=GHC.TypeLits.Extra.Solver -fplugin=GHC.TypeLits.Normalise --vhdl -fclash-error-extra -fclash-compile-ultra ./Pro
ject.hs
WARNING: Clash is linked statically, which can lead to long startup times.
See https://gitlab.haskell.org/ghc/ghc/issues/15524

GHC: Parsing and optimising modules took: 1.802s
GHC: Loading external modules from interface files took: 0.454s
GHC: Parsing annotations took: 0.001s
Clash: Parsing and compiling primitives took 0.066s
GHC+Clash: Loading modules cumulatively took 2.539s
Clash: Compiling Project.topEntity
Clash: Normalisation took 0.010s

Project.hs:49:1: error:

    Clash.Netlist(277): Clash.Core.Util(844): Cannot reduce to an integer:
    Clash.Class.BitPack.BitSize[8214565720323789400]
      (Project.U16[8214565720323850163]
         Project.WireRep[8214565720323850167])

    The source location of the error is not exact, only indicative, as it is acquired
    after optimizations. The actual location of the error can be in a function that is
    inlined. To prevent inlining of those functions, annotate them with a NOINLINE pragma.
   |
49 | topEntity _ = pure (unpack 0 == Record (U16 0) (U16 0))
   | ^^^^^^^^^
make: *** [clash-example] Error 1
christiaanb added a commit that referenced this issue Mar 23, 2020
Before, `funSubst`, the heart of our type-family resolution
engine, could only deal with `a -> b` and `F a b` on both the
matching side and argument side. Now it works on all applications,
including things of the form `f a`.

Fixes #1242
@alastairbarnett
Copy link
Author

This fix seems to have solved the issue. Thankyou.

christiaanb added a commit that referenced this issue Mar 24, 2020
Before, `funSubst`, the heart of our type-family resolution
engine, could only deal with `a -> b` and `F a b` on both the
matching side and argument side. Now it works on all applications,
including things of the form `f a`.

Fixes #1242
christiaanb added a commit that referenced this issue Mar 24, 2020
Before, `funSubst`, the heart of our type-family resolution
engine, could only deal with `a -> b` and `F a b` on both the
matching side and argument side. Now it works on all applications,
including things of the form `f a`.

Fixes #1242
mergify bot pushed a commit that referenced this issue Mar 24, 2020
Before, `funSubst`, the heart of our type-family resolution
engine, could only deal with `a -> b` and `F a b` on both the
matching side and argument side. Now it works on all applications,
including things of the form `f a`.

Fixes #1242

(cherry picked from commit 5477a2f)
christiaanb added a commit that referenced this issue Mar 24, 2020
Before, `funSubst`, the heart of our type-family resolution
engine, could only deal with `a -> b` and `F a b` on both the
matching side and argument side. Now it works on all applications,
including things of the form `f a`.

Fixes #1242

(cherry picked from commit 5477a2f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants