Walk the DOM and emit the trace names
authorCesar Strauss <cestrauss@gmail.com>
Sat, 22 Aug 2020 19:14:53 +0000 (16:14 -0300)
committerCesar Strauss <cestrauss@gmail.com>
Sat, 22 Aug 2020 19:46:06 +0000 (16:46 -0300)
Descend into the children of each group, while emitting the group
delimiters.

src/soc/experiment/alu_fsm.py

index 067ea720fd8784e89e3a8cb590a9966257bd20d9..f493983aba690003c7792d7519921fd424b2a559 100644 (file)
@@ -206,7 +206,7 @@ class Shifter(Elaboratable):
 
 
 # Write a formatted GTKWave "save" file
-def write_gtkw(base_name, top_dut_name, loc):
+def write_gtkw_v1(base_name, top_dut_name, loc):
     # hierarchy path, to prepend to signal names
     dut = top_dut_name + "."
     # color styles
@@ -251,6 +251,46 @@ def write_gtkw(base_name, top_dut_name, loc):
             gtkw.trace(dut + "n_ready_i", color=style_input)
 
 
+# write a GTKWave document according to the supplied style and DOM
+# TODO: Apply styles
+def write_gtkw(gtkw_name, vcd_name, gtkw_style, gtkw_dom,
+               loc=None, zoom=-22.9, marker=-1):
+    with open(gtkw_name, "wt") as gtkw_file:
+        gtkw = GTKWSave(gtkw_file)
+        if loc is not None:
+            gtkw.comment("Auto-generated by " + loc)
+        gtkw.dumpfile(vcd_name)
+        # set a reasonable zoom level
+        # also, move the marker to an interesting place
+        gtkw.zoom_markers(zoom, marker)
+
+        # recursively walk the DOM
+        def walk(dom):
+            for node in dom:
+                node_name = None
+                children = None
+                # node is a signal name string
+                if isinstance(node, str):
+                    node_name = node
+                # node is a tuple
+                # could be a signal or a group
+                elif isinstance(node, tuple):
+                    node_name = node[0]
+                    # node is a group if it has a child list
+                    if isinstance(node[-1], list):
+                        children = node[-1]
+                # emit the group delimiters and walk over the child list
+                if children is not None:
+                    gtkw.begin_group(node_name)
+                    walk(children)
+                    gtkw.end_group(node_name)
+                # emit a trace, if the node is a signal
+                elif node_name is not None:
+                    gtkw.trace(node_name)
+
+        walk(gtkw_dom)
+
+
 def test_shifter():
     m = Module()
     m.submodules.shf = dut = Shifter(8)
@@ -264,7 +304,7 @@ def test_shifter():
         f.write(il)
 
     # Write the GTKWave project file
-    write_gtkw("test_shifter", "top.shf", __file__)
+    write_gtkw_v1("test_shifter", "top.shf", __file__)
 
     # Describe a GTKWave document
     # Uses a split CSS + DOM approach, where style is separated from
@@ -341,8 +381,9 @@ def test_shifter():
         ]),
     ]
 
-    # TODO: Read and interpret the mini-language above, writing
-    # TODO: the corresponding GTKWave document.
+    write_gtkw("test_shifter_v2.gtkw", "test_shifter.vcd",
+               gtkwave_style, gtkwave_desc,
+               loc=__file__, marker=10500000)
 
     sim = Simulator(m)
     sim.add_clock(1e-6)