This system is very WIP, and is therefore pretty janktastic. The general idea of the circuit renderer is that you create a vector drawing of your circuit with special labels for the circuit state you want to render. The only svg program I have tested this with is inkscape, and I recommend against using other drawing programs.
As an example we will use a very simple circuit:
This circuit has a register, and we want to see how its state evolves, thus we add a label. The name of the register is "Reg_A", which will be replaced by the actual value as the circuit is simulated. We indicate this by adding "_field" as a postfix.
Next we make a test for our circuit
class Adder() extends Module {
val io = IO(
new Bundle {
val reg_a = Output(UInt(32.W))
}
)
val reg_a = RegInit(0.U(8.W))
reg_a := reg_a + 1.U
io.reg_a := reg_a
}
Next we create a test, using an extension of PeekPokeTester
class AdderTester(c: Adder) extends PeekPokeTesterLogger(c) {
// ^^^^^^^^^^^^^^^^^^^^^^^ This is an extension of the regular peek poke tester
// Tells us which signals should be logged
override def ioLoggers = List(c.io)
for(ii <- 0 until 10){
step(1)
}
// Writes the log to disk
writeLog
}
When the addertester is run it will record the state of c.io for every timestep and store it.
When testing is done, calling writeLog will search for an SVG whose name matches the tested device in
the resources folder.
For adder this corresponds to src/test/resources/svgs/Adder.svg
The svg is loaded, and every value with the _field postfix is replaced with the recorded value sharing
its name.
In the simple adder circuit the only value in io is reg_a which matches Reg_A_field.
By running
testOnly Ex0.SVGSpec 10 svg files will be created, showing the state of the circuit for every step
You can now see the output svgs in the svgOutputs folder.

If you want to view them as pngs and you have inkscape installed you can run ./convert.sh to get png output instead.
For a more fully fledged example take a look at src/test/scala/SVGNestedSpec.scala
which can be run with
testOnly Ex0.SVGSNestedSpec
The time invested in drawing a circuit, laying out fields etc is likely not worth it. However, for the 5-stage RISCV pipeline the answer is definitely a yes! In order to get a feel for this approach I recommend trying to debug the matrix multiplier unit (last exercise) with this approach. To do so you need to do the following steps:
(Or you could repurpose the SVGSNestedSpec)
You can add as much detail as you want here, the only thing the parser looks for is text fields that are postfixed with "_field". The fields I would be interested in are the row and column counters, and the dot product accumulator state. Save the svg as /src/test/resources/svgs/MatMul.svg
The peek poke logger can only observe the top level IO modules, so the signals you want to record must be made available. This approach is shown in the chisel introduction.
Your tester should extend PeekPokeTesterLogger. In your test you need to override the ioLoggers function to record the ports you want to monitor (typically io, maybe a special debug port)
At the end of your test add writeLog in order to actually write the svgs
If everything goes smooth you can now take a look at the SVG output, or if you have inkscape render it as an svg