until -package:numeric-prelude -package:util -package:hedgehog -package:extra -package:monad-loops -package:netwire -package:IfElse -is:exact package:clash-prelude

until p f yields the result of applying f until p holds.
Simulate a component until it matches a condition It prints a message of the form
Signal sampled for N cycles until value X
NB: This function is not synthesizable

Example with test bench

A common usage is with a test bench using outputVerifier. NB: Since this uses assert, when using clashi, read the note at Clash.Explicit.Testbench#assert-clashi.
import Clash.Prelude
import Clash.Explicit.Testbench

topEntity
:: Signal System Int
-> Signal System Int
topEntity = id

testBench
:: Signal System Bool
testBench = done
where
testInput = stimuliGenerator clk rst $(listToVecTH [1 :: Int .. 10])
expectedOutput =
outputVerifier' clk rst $(listToVecTH $ [1 :: Int .. 9] <> [42])
done = expectedOutput $ topEntity testInput
clk = tbSystemClockGen (not <$> done)
rst = systemResetGen
> runUntil id testBench


cycle(<Clock: System>): 10, outputVerifier
expected value: 42, not equal to actual value: 10
Signal sampled for 11 cycles until value True
When you need to verify multiple test benches, the following invocations come in handy:
> mapM_ (runUntil id) [ testBenchA, testBenchB ]
or when the test benches are in different clock domains:
testBenchA :: Signal DomA Bool
testBenchB :: Signal DomB Bool
> sequence_ [ runUntil id testBenchA, runUntil id testBenchB ]
Simulate a component until it matches a condition If the given component has not yet been given a clock, reset, or enable line, runUntil will supply them. The reset will be asserted for a single cycle. It prints a message of the form
Signal sampled for N cycles until value X
NB: This function is not synthesizable

Example with test bench

A common usage is with a test bench using outputVerifier. NB: Since this uses assert, when using clashi, read the note at Clash.Explicit.Testbench#assert-clashi.
import Clash.Prelude
import Clash.Explicit.Testbench

topEntity
:: Signal System Int
-> Signal System Int
topEntity = id

testBench
:: Signal System Bool
testBench = done
where
testInput = stimuliGenerator clk rst $(listToVecTH [1 :: Int .. 10])
expectedOutput =
outputVerifier' clk rst $(listToVecTH $ [1 :: Int .. 9] <> [42])
done = expectedOutput $ topEntity testInput
clk = tbSystemClockGen (not <$> done)
rst = systemResetGen
> runUntil id testBench


cycle(<Clock: System>): 10, outputVerifier
expected value: 42, not equal to actual value: 10
Signal sampled for 11 cycles until value True
When you need to verify multiple test benches, the following invocations come in handy:
> mapM_ (runUntil id) [ testBenchA, testBenchB ]
or when the test benches are in different clock domains:
testBenchA :: Signal DomA Bool
testBenchB :: Signal DomB Bool
> sequence_ [ runUntil id testBenchA, runUntil id testBenchB ]