Demonstrates creating stylish GTKWave "save" files from python
authorCesar Strauss <cestrauss@gmail.com>
Thu, 13 Aug 2020 22:40:35 +0000 (19:40 -0300)
committerCesar Strauss <cestrauss@gmail.com>
Sat, 15 Aug 2020 09:27:26 +0000 (06:27 -0300)
This is inspired on the use of the vcd.gtkw module in nMigen, used
internally to create "save" files of selected Signals, for
"Simulator.write_vcd".

However, the vcd.gtkw module exposes a great deal of extra possibilities,
like:

1) Individual trace colors.
For instance, use different color styles for input, output, debug and
internal traces.
2) Numeric bases besides the default hex.
3) Collapsible trace groups
Useful to hide and show, at once, groups of debug, internal and
sub-module traces.
Select the opening or closing brace, then use the T key.
4) Comments in the signal names pane
5) Change the displayed name of a trace
6) Sane default for initial zoom level
7) Place markers on interesting places
8) Put the generating file name as a comment in the file

setup.py
src/soc/experiment/alu_fsm.py

index bbe5e144786b32dad76ea934dcdaeb5eb2d0c470..737c7c996e993552f93f940eca194d592b06b663 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -16,6 +16,7 @@ install_requires = [
     'nmigen-soc',  # install manually from git.libre-soc.org
     'ply',  # needs to be installed manually
     'astor',
+    'pyvcd',  # for stylish GTKWave save files
 
     # install from https://salsa.debian.org/Kazan-team/power-instruction-analyzer
     'power-instruction-analyzer',
index 1bc9661dafcab7627561a55ed9f0b9c92099261f..3a3d9db111af3d9152d21017b96048746662562f 100644 (file)
@@ -29,6 +29,8 @@ from nmutil.iocontrol import PrevControl, NextControl
 from soc.fu.base_input_record import CompOpSubsetBase
 from soc.decoder.power_enums import (MicrOp, Function)
 
+from vcd.gtkw import GTKWSave, GTKWColor
+
 
 class CompFSMOpSubset(CompOpSubsetBase):
     def __init__(self, name=None):
@@ -203,6 +205,43 @@ class Shifter(Elaboratable):
         return list(self)
 
 
+# Write a formatted GTKWave "save" file
+def write_gtkw(base_name, top_dut_name, loc):
+    # hierarchy path, to prepend to signal names
+    dut = top_dut_name + "."
+    # color styles
+    style_input = GTKWColor.orange
+    style_output = GTKWColor.yellow
+    with open(base_name + ".gtkw", "wt") as gtkw_file:
+        gtkw = GTKWSave(gtkw_file)
+        gtkw.comment("Auto-generated by " + loc)
+        gtkw.dumpfile(base_name + ".vcd")
+        # set a reasonable zoom level
+        # also, move the marker to an interesting place
+        gtkw.zoom_markers(-22.9, 10500000)
+        gtkw.trace(dut + "clk")
+        # place a comment in the signal names panel
+        gtkw.blank("Shifter Demonstration")
+        with gtkw.group("prev port"):
+            gtkw.trace(dut + "op__sdir", color=style_input)
+            # demonstrates using decimal base (default is hex)
+            gtkw.trace(dut + "p_data_i[7:0]", color=style_input,
+                       datafmt='dec')
+            gtkw.trace(dut + "p_shift_i[7:0]", color=style_input,
+                       datafmt='dec')
+            gtkw.trace(dut + "p_valid_i", color=style_input)
+            gtkw.trace(dut + "p_ready_o", color=style_output)
+        with gtkw.group("internal"):
+            gtkw.trace(dut + "fsm_state")
+            gtkw.trace(dut + "count[3:0]")
+            gtkw.trace(dut + "shift_reg[7:0]", datafmt='dec')
+        with gtkw.group("next port"):
+            gtkw.trace(dut + "n_data_o[7:0]", color=style_output,
+                       datafmt='dec')
+            gtkw.trace(dut + "n_valid_o", color=style_output)
+            gtkw.trace(dut + "n_ready_i", color=style_input)
+
+
 def test_shifter():
     m = Module()
     m.submodules.shf = dut = Shifter(8)
@@ -214,6 +253,10 @@ def test_shifter():
     il = rtlil.convert(dut, ports=dut.ports())
     with open("test_shifter.il", "w") as f:
         f.write(il)
+
+    # Write the GTKWave project file
+    write_gtkw("test_shifter", "top.shf", __file__)
+
     sim = Simulator(m)
     sim.add_clock(1e-6)