clash-compiler
clash-compiler copied to clipboard
Constants do not get propagated to blackboxes requiring them in some situations
Consider:
module Test where
import Clash.Explicit.Prelude
topEntity
:: Clock System
-> Reset System
-> Enable System
-> Vec 3 (Signal System Int)
topEntity clk rst gen =
map (register clk rst gen) (iterateI succ 0) <*> pure 3
register
requires its reset value to be a constant. Clash doesn't seem to propagate it however:
Test.hs:10:1: error:
Clash.Netlist.BlackBox(183): Couldn't instantiate blackbox for Clash.Signal.Internal.register#. Verification procedure reported:
Argument 5 should be literal, as blackbox used ~CONST[5], but was:
Identifier "~ARGN[1][0]" Nothing
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.
|
10 | topEntity clk rst gen =
| ^^^^^^^^^
The core of the problem is that Clash ends up with the following core:
result[8] :: Clash.Sized.Vector.Vec[8214565720323789611]
3
(Clash.Signal.Internal.Signal[8214565720323789571]
"System"
GHC.Types.Int[3674937295934324766])
= Clash.Sized.Vector.zipWith
@GHC.Types.Int[3674937295934324766]
@(Clash.Signal.Internal.Signal[8214565720323789571]
"System"
GHC.Types.Int[3674937295934324766])
@(Clash.Signal.Internal.Signal[8214565720323789571]
"System"
GHC.Types.Int[3674937295934324766])
@3
(λ(initial[6989586621679073303] :: GHC.Types.Int[3674937295934324766]) ->
λ(i[6989586621679073304] :: Clash.Signal.Internal.Signal[8214565720323789571]
"System"
GHC.Types.Int[3674937295934324766]) ->
Clash.Signal.Internal.register# @"System"
@GHC.Types.Int[3674937295934324766]
(Clash.Transformations.removedArg
@(Clash.Signal.Internal.KnownDomain[8214565720323789548]
"System"))
(Clash.Transformations.removedArg
@(Clash.XException.NFDataX[8214565720323789616]
GHC.Types.Int[3674937295934324766]))
clk[6989586621679069551][LocalId]
rst[6989586621679069552][LocalId]
gen[6989586621679069553][LocalId]
initial[6989586621679073303][LocalId]
initial[6989586621679073303][LocalId]
i[6989586621679073304][LocalId])
xs[8286623314361782424][LocalId]
(Clash.Sized.Vector.replicate @3
@(Clash.Signal.Internal.Signal[8214565720323789571]
"System"
GHC.Types.Int[3674937295934324766])
(Clash.Promoted.Nat.SNat[8214565720323789502] @3
3)
(GHC.Types.I# 3))
This is representable, so reduceNonRepPrim
won't fire. Ideally we'd somehow track / annotate what vars need to be a constant. Preferably across global binders, which could potentially eliminate a lot of work in constantSpec
.