Open kleinreact opened 1 year ago
I tried to reproduce this locally, but failed in two different ways so far:
Clash error call:
assignmentWith: Cannot assign as Proc Blocking after Cont for RawIdentifier "result" Nothing [("unsafeMake",SrcLoc {srcLocPackage = "clash-lib-1.7.0-inplace", srcLocModule = "Clash.Netlist.Id", srcLocFile = "src/Clash/Netlist/Id.hs", srcLocStartLine = 246, srcLocStartCol = 20, srcLocEndLine = 246, srcLocEndCol = 30}),("unsafeFromCoreId",SrcLoc {srcLocPackage = "clash-lib-1.7.0-inplace", srcLocModule = "Clash.Netlist", srcLocFile = "src/Clash/Netlist.hs", srcLocStartLine = 486, srcLocStartCol = 29, srcLocEndLine = 486, srcLocEndCol = 48})]
CallStack (from HasCallStack):
error, called at src/Clash/Netlist/Util.hs:1235:7 in clash-lib-1.7.0-inplace:Clash.Netlist.Util
assignmentWith, called at src/Clash/Netlist/Util.hs:1285:3 in clash-lib-1.7.0-inplace:Clash.Netlist.Util
assignmentWith: Cannot assign as Proc Blocking after Cont
Hey, this error picking up actual wrong netlist generation instead of me messing up while working on a netlist PR :tada:
Something somewhere is generating duplicate signal names.
So far I've shrunk it to:
{-# OPTIONS_GHC -XPartialTypeSignatures #-}
module Test2407 where
import Clash.Prelude
import qualified Clash.Cores.Xilinx.Floating as F
import qualified Clash.Signal.Delayed as D
topEntity clk rst ena = withClockResetEnable @System clk rst ena $ popCountTest @System
popCountTest ::
forall dom.
HiddenClockResetEnable dom =>
_
popCountTest = r_k
where
r_k :: DSignal dom F.FromS32DefDelay Float
r_k = F.fromS32 $ D.fromSignal (popCountTo32 <$> mask)
mask :: Signal dom (BitVector 3)
mask = pure $ pack $ repeat high -- broken
-- mask = pure $ complement 0 -- not broken
popCountTo32 :: KnownNat n => BitVector n -> Signed 32
popCountTo32 = resize . bitCoerce . popCount
Which generates:
module topEntity
(...);
[...]
wire signed [63:0] c$app_arg;
wire signed [63:0] c$app_arg;
wire signed [63:0] c$app_arg;
wire signed [63:0] c$app_arg;
[...]
assign c$app_arg = $unsigned({{(64-1) {1'b0}},c$bv});
assign c$app_arg = $unsigned({{(64-1) {1'b0}},c$bv_0});
assign c$app_arg = $unsigned({{(64-1) {1'b0}},c$bv_1});
assign c$app_arg = $unsigned({{(64-1) {1'b0}},c$bv_2});
[...]
All of there c$app_arg
are different signals, but they've been assigned the same name in Verilog
One thing you can try is adding a uniqueness check on the function which unsafely creates a new netdecl and get the Callstack to the second c$app_arg
which is declared
I can't reproduce this at all. What GHC / Clash commit are you guys on?
For those hunting down a reproducer: does commenting out https://github.com/clash-lang/clash-compiler/blob/8894dd63aae5522845b7e37ab3c0d6cf10a084a8/clash-lib/src/Clash/Normalize/Strategy.hs#L55 solve the issue?
I can reproduce @leonschoorl's last example in Verilog on current master
with GHC 9.2.4. Trying @christiaanb's suggestion does indeed appear to fix this - the resulting Verilog code looks very similar to the working VHDL code, i.e.
But also: what the heck Christiaan
Ah, maybe I see. Is this something to do with the evaluator rules for xToBV
not being able to fire because the BitVector
argument to it becomes a pack#
of a Vec
which is an unsafeCoerce#
(due to it being a map
that turns a Bit
to a BitVector 1
which is replaced with unsafeCoerce#
)?
EDIT: I think so, in the fixed version we see the BitVector
s are chomped down to constants and the xToBV
calls are all removed in flattenExpr
.
Everyone running around, panic, papers flying. A beam of light shines down from the heavens. Everyone is silent. Suddenly a deep voice cuts through the ignorance.
For those hunting down a reproducer: does commenting out
solve the issue?
And so it shall be. People are weeping. Churches are being erected. The world is not as it was before.
Come for the nerd sniping, stay for the quasi-religious fan-fiction
To be fair, I looked at the log earlier, and was triggered by the GHC.Prim.unsafeCoerce#
as none of the code originally contained calls to unsafeCoerce; and collapseRHSNoops
was the only function that introduces them.
So there's two possibilities:
collapseRHSNoops
is buggedcollapseRHSNoops
exposes a bug in netlistgen, i.e. disabling the transformation is just a red herring.
We recently tried to synthesize some simple popCount extension for KnownSized BitVectors for the bittide-hardware project
leading to very long Clash warnings and multi-driven net pin errors. The observed error only appears in a very specific context and, unfortunately, we were not able to reproduce it with a small standalone example yet. Therefore, we assume that its not only the
popCountTo32
synthesis, but also the given interplay with other components, which leads to the final error in Clash.We still tried to reduce it to a minimal counterexample as much as possible, given by the following code. The full code and context can be found here. The used GHC and Clash versions are fixed here.
The comments should give some insights of what we already tired. The issue has been analyzed in this Bittide PR. The
clash compiler
output withDebugApplied
enabled is attached: DebugAppliedLog.zip.We can run a more dedicated analysis, but this requires some more detailed analysis strategy than what we have at the moment.