# 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
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)
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
]),
]
- # 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)