From: Cesar Strauss Date: Fri, 28 Aug 2020 09:55:10 +0000 (-0300) Subject: Move new write_gtkw and its example to nmutil X-Git-Tag: semi_working_ecp5~233 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=855d9363c869ad84a2fabd006ca22cb28ab8fa38 Move new write_gtkw and its example to nmutil But keep using it to generate the GTKWave document for this unit test. --- diff --git a/setup.py b/setup.py index 737c7c99..bbe5e144 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,6 @@ 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', diff --git a/src/soc/experiment/alu_fsm.py b/src/soc/experiment/alu_fsm.py index 596fc3d4..28bbde65 100644 --- a/src/soc/experiment/alu_fsm.py +++ b/src/soc/experiment/alu_fsm.py @@ -29,7 +29,7 @@ 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 +from nmutil.gtkw import write_gtkw class CompFSMOpSubset(CompOpSubsetBase): @@ -205,196 +205,6 @@ class Shifter(Elaboratable): return list(self) -# Write a formatted GTKWave "save" file -def write_gtkw_v1(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 - style_debug = GTKWColor.red - 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("debug"): - gtkw.blank("Some debug statements") - # change the displayed name in the panel - gtkw.trace("top.zero", alias='zero delay shift', - color=style_debug) - gtkw.trace("top.interesting", color=style_debug) - gtkw.trace("top.test_case", alias="test case", color=style_debug) - gtkw.trace("top.msg", color=style_debug) - 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 write_gtkw(gtkw_name, vcd_name, gtkw_dom, gtkw_style=None, - module=None, loc=None, color=None, base=None, - zoom=-22.9, marker=-1): - """ Write a GTKWave document according to the supplied style and DOM. - - :param gtkw_name: name of the generated GTKWave document - :param vcd_name: name of the waveform file - :param gtkw_dom: DOM style description for the trace pane - :param gtkw_style: style for signals, classes and groups - :param module: default module - :param color: default trace color - :param base: default numerical base - :param loc: source code location to include as a comment - :param zoom: initial zoom level, in GTKWave format - :param marker: initial location of a marker - - **gtkw_style format** - - Syntax: ``{selector: {attribute: value, ...}, ...}`` - - "selector" can be a signal, class or group - - Signal groups propagate most attributes to their children - - Attribute choices: - - * module: instance path, for prepending to the signal name - * color: trace color - * base: numerical base for value display - * display: alternate text to display in the signal pane - * comment: comment to display in the signal pane - - **gtkw_dom format** - - Syntax: ``[signal, (signal, class), (group, [children]), comment, ...]`` - - The DOM is a list of nodes. - - Nodes are signals, signal groups or comments. - - * signals are strings, or tuples: ``(signal name, class, class, ...)`` - * signal groups are tuples: ``(group name, class, class, ..., [nodes])`` - * comments are: ``{'comment': 'comment string'}`` - - In place of a class name, an inline class description can be used. - ``(signal, {attribute: value, ...}, ...)`` - """ - colors = { - 'blue': GTKWColor.blue, - 'cycle': GTKWColor.cycle, - 'green': GTKWColor.green, - 'indigo': GTKWColor.indigo, - 'normal': GTKWColor.normal, - 'orange': GTKWColor.orange, - 'red': GTKWColor.red, - 'violet': GTKWColor.violet, - 'yellow': GTKWColor.yellow, - } - - 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) - - # create an empty style, if needed - if gtkw_style is None: - gtkw_style = dict() - - # create an empty root selector, if needed - root_style = gtkw_style.get('', dict()) - - # apply styles to the root selector, if provided - if module is not None: - root_style['module'] = module - if color is not None: - root_style['color'] = color - if base is not None: - root_style['base'] = base - # base cannot be None, use 'hex' by default - if root_style.get('base') is None: - root_style['base'] = 'hex' - - # recursively walk the DOM - def walk(dom, style): - for node in dom: - node_name = None - children = None - # copy the style from the parent - node_style = style.copy() - # node is a signal name string - if isinstance(node, str): - node_name = node - # apply style from node name, if specified - if node_name in gtkw_style: - node_style.update(gtkw_style[node_name]) - # node is a tuple - # could be a signal or a group - elif isinstance(node, tuple): - node_name = node[0] - # collect styles from the selectors - # order goes from the most specific to most generic - # which means earlier selectors override later ones - for selector in reversed(node): - # update the node style from the selector - if isinstance(selector, str): - if selector in gtkw_style: - node_style.update(gtkw_style[selector]) - # apply an inline style description - elif isinstance(selector, dict): - node_style.update(selector) - # node is a group if it has a child list - if isinstance(node[-1], list): - children = node[-1] - # comment - elif isinstance(node, dict): - if 'comment' in node: - gtkw.blank(node['comment']) - # emit the group delimiters and walk over the child list - if children is not None: - gtkw.begin_group(node_name) - # pass on the group style to its children - walk(children, node_style) - gtkw.end_group(node_name) - # emit a trace, if the node is a signal - elif node_name is not None: - signal_name = node_name - # prepend module name to signal - if 'module' in node_style: - node_module = node_style['module'] - if node_module is not None: - signal_name = node_module + '.' + signal_name - node_color = colors.get(node_style.get('color')) - node_base = node_style.get('base') - display = node_style.get('display') - gtkw.trace(signal_name, color=node_color, - datafmt=node_base, alias=display) - - walk(gtkw_dom, root_style) - - def test_shifter(): m = Module() m.submodules.shf = dut = Shifter(8) @@ -407,9 +217,6 @@ def test_shifter(): with open("test_shifter.il", "w") as f: f.write(il) - # Write the GTKWave project file - write_gtkw_v1("test_shifter", "top.shf", __file__) - # Describe a GTKWave document # Style for signals, classes and groups @@ -464,7 +271,7 @@ def test_shifter(): ]), ] - write_gtkw("test_shifter_v2.gtkw", "test_shifter.vcd", + write_gtkw("test_shifter.gtkw", "test_shifter.vcd", gtkwave_desc, gtkwave_style, module="top.shf", loc=__file__, marker=10500000)