Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DualSimTracer doc #222

Merged
merged 3 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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()
}
}
}
}
30 changes: 30 additions & 0 deletions source/SpinalHDL/Simulation/bootstraps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Either 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 other simulation had a failure.
Dolu1990 marked this conversation as resolved.
Show resolved Hide resolved

To do this, you can use the DualSimTracer utility, which will ask you the compiled hardware, the window of time you want to capture the wave before falure, and a seed.
Dolu1990 marked this conversation as resolved.
Show resolved Hide resolved

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.