I get a very slow simulation of values in Clashi for the following function.
I don’t see anything wrong with the generated verilog code though.
I guess that the simulator might be stuck in some recursive calls. Any ideas?
“Clashi, version 1.6.4 (using clash-lib, version 1.6.4)”
import Clash.Prelude
hotPotato :: HiddenClockResetEnable dom => Int -> Signal dom Int
hotPotato n = register 0 (mux (hotPotato n .==. pure (n-1)) 0 (hotPotato n + 1))
topEntity :: Clock System -> Reset System -> Enable System -> Signal System Int
topEntity = exposeClockResetEnable (hotPotato 8)
The following is the summary based on the replies from Christiaan in Slack.
Restructuring the code as below we no longer observe this problem.
hotPotato :: HiddenClockResetEnable dom => Int -> Signal dom Int
hotPotato n =
let s = register 0 (mux (s .==. pure (n-1)) 0 (s + 1)) in s
This is likely due to the memoization of results in the let-binding form. The results were not memoized in the original form making Haskell recalculate previous values in each clock cycle.
He also pointed out the limitations of Clash with a recursive function.
For example, Clash can’t generate a VHDL, or Verilog for the following code.
fibR :: Word -> Word
fibR 0 = 0
fibR 1 = 1
fibR n = fibR (n-1) + fibR (n-2)
When taken a structural view, it gives an infinitely deep structure making it impossible to layout a finite circuit.
Further details can be found here.
2 Likes