diff --git a/examples/src/main/scala/spinaldoc/libraries/sim/DualSimExample.scala b/examples/src/main/scala/spinaldoc/libraries/sim/DualSimExample.scala new file mode 100644 index 00000000000..2975be7363b --- /dev/null +++ b/examples/src/main/scala/spinaldoc/libraries/sim/DualSimExample.scala @@ -0,0 +1,30 @@ +package spinaldoc.libraries.sim + +import spinal.core._ +import spinal.core.sim._ +import spinal.lib.misc.test.DualSimTracer + +class Toplevel extends Component{ + val counter = out(Reg(UInt(16 bits))) init(0) + counter := counter + 1 +} + +object Example extends App { + val compiled = SimConfig.withFstWave.compile(new Toplevel()) + + DualSimTracer(compiled, window = 10000, seed = 42){dut=> + dut.clockDomain.forkStimulus(10) + dut.clockDomain.onSamplings{ + val value = dut.counter.toInt + + if(value % 0x1000 == 0){ + println(f"Value=0x$value%x at ${simTime()}") + } + + // Throw a simulation failure after 64K cycles + if(value == 0xFFFF){ + simFailure() + } + } + } +} diff --git a/source/SpinalHDL/Simulation/bootstraps.rst b/source/SpinalHDL/Simulation/bootstraps.rst index 212fb5aad51..39db77eaf6d 100644 --- a/source/SpinalHDL/Simulation/bootstraps.rst +++ b/source/SpinalHDL/Simulation/bootstraps.rst @@ -189,3 +189,33 @@ For instance, to make the simulation fail after 1000 times the duration of a clo val period = 10 dut.clockDomain.forkStimulus(period) SimTimeout(1000 * period) + +Capturing wave for a given window before failure +------------------------------------------------ + +In the case you have a very long simulation, and you don't want to capture the wave on all of it (too bug, too slow), you have mostly 2 ways to do it. + +Either you know already at which ``simTime`` the simulation failed, in which case you can do the following in your testbench : + +.. code-block:: scala + + disableSimWave() + delayed(timeFromWhichIWantToCapture)(enableSimWave()) + +Or you can run a dual lock-step simulation, with one running a bit delayed from the the other one, and which will start recording the wave once the leading simulation had a failure. + +To do this, you can use the DualSimTracer utility, with parameters for the compiled hardware, the window of time you want to capture before failure, and a seed. + +Here is an example : + +.. literalinclude:: /../examples/src/main/scala/spinaldoc/libraries/sim/DualSimExample.scala + :language: scala + +This will generate the following file structure : + +- simWorkspace/Toplevel/explorer/stdout.log : stdout of the simulation which is ahead +- simWorkspace/Toplevel/tracer/stdout.log : stdout of the simulation doing the wave tracing +- simWorkspace/Toplevel/tracer.fst : Waveform of the failure + +The scala terminal will show the explorer simulation stdout. +