Open
Description
The following:
module Test where
import Clash.Prelude
import Data.Constraint
import Data.Proxy
import Unsafe.Coerce
data T depth = T (BitVector depth) deriving (Generic)
instance (1 <= CLog 2 depth, KnownNat depth) => NFDataX (T depth)
-- | if (2 <= n) holds, then (1 <= CLog 2 n) also holds.
oneLeCLog2n :: forall n . (2 <= n) => Proxy n -> Dict (1 <= CLog 2 n)
oneLeCLog2n Proxy = unsafeCoerce (Dict :: Dict ())
f ::
forall dom depth.
( HiddenClockResetEnable dom
, KnownNat depth
, 2 <= depth ) =>
Proxy depth ->
Signal dom Bool ->
Signal dom Bool
f Proxy =
case oneLeCLog2n (Proxy @depth) of
Dict -> mealy go (T 0)
where
go :: T depth -> Bool -> (T depth, Bool)
go (T n) True = (T (n + 1), False)
go (T n) False = (T (n - 1), True)
{-# NOINLINE f #-}
topEntity clk rst ena =
withClockResetEnable clk rst ena $
f @System @2 Proxy
{-# NOINLINE topEntity #-}
causes:
<no location info>: error:
Clash error call:
zipEqual: left list is longer
CallStack (from HasCallStack):
error, called at src/Data/List/Extra.hs:124:19 in clash-lib-1.7.0-inplace:Data.List.Extra
zipEqual, called at src/Clash/Normalize/Transformations/Case.hs:203:19 in clash-lib-1.7.0-inplace:Clash.Normalize.Transformations.Case
caseCon', called at src/Clash/Normalize/Transformations/Case.hs:149:32 in clash-lib-1.7.0-inplace:Clash.Normalize.Transformations.Case
caseCon, called at src/Clash/Normalize/Strategy.hs:91:36 in clash-lib-1.7.0-inplace:Clash.Normalize.Strategy
In other examples Clash introduces free variables in caseCon
(but I've yet to make a small reproducer for that).
Printing the arguments given to zipEqual
gives:
xs1: [ Id
{ varName =
Name
{ nameSort = Internal
, nameOcc = "c$sel"
, nameUniq = 2
, nameLoc = UnhelpfulSpan UnhelpfulNoLocationInfo
}
, varUniq = 2
, varType =
AppTy
(AppTy
(AppTy
(AppTy
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.Prim.~#"
, nameUniq = 3674937295934324842
, nameLoc = UnhelpfulSpan UnhelpfulNoLocationInfo
}))
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.Types.Bool"
, nameUniq = 3674937295934324744
, nameLoc =
RealSrcSpan SrcSpanMultiLine "Test.hs" 16 1 23 18 Nothing
})))
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.Types.Bool"
, nameUniq = 3674937295934324744
, nameLoc =
RealSrcSpan SrcSpanMultiLine "Test.hs" 16 1 23 18 Nothing
})))
(AppTy
(AppTy
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.TypeNats.<=?"
, nameUniq = 3674937295934325074
, nameLoc =
RealSrcSpan SrcSpanMultiLine "Test.hs" 16 1 23 18 Nothing
}))
(LitTy (NumTy 1)))
(AppTy
(AppTy
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.TypeLits.Extra.CLog"
, nameUniq = 8214565720323785211
, nameLoc =
RealSrcSpan SrcSpanMultiLine "Test.hs" 16 1 23 18 Nothing
}))
(LitTy (NumTy 2)))
(LitTy (NumTy 2)))))
(ConstTy
(TyCon
Name
{ nameSort = User
, nameOcc = "GHC.Types.True"
, nameUniq = 3891110078048108586
, nameLoc =
RealSrcSpan SrcSpanMultiLine "Test.hs" 16 1 23 18 Nothing
}))
, idScope = LocalId
}
]
left args: []
Workaround: add NOINLINE
to oneLeCLog2n