diff options
-rw-r--r-- | src/python/m5/util/dot_writer.py | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/python/m5/util/dot_writer.py b/src/python/m5/util/dot_writer.py index 52d0b4b62..fbeb655ca 100644 --- a/src/python/m5/util/dot_writer.py +++ b/src/python/m5/util/dot_writer.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012-2013 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -41,15 +41,16 @@ # System visualization using DOT # # While config.ini and config.json provide an almost complete listing -# of a system's components and connectivity, they lack a birds-eye view. -# The output generated by do_dot() is a DOT-based figure (pdf) and its -# source dot code. Nodes are components, and edges represent -# the memory hierarchy: the edges are directed, from a master to a slave. -# Initially all nodes are generated, and then all edges are added. -# do_dot should be called with the top-most SimObject (namely root -# but not necessarily), the output folder and the output dot source -# filename. From the given node, both processes (node and edge creation) -# is performed recursivly, traversing all children of the given root. +# of a system's components and connectivity, they lack a birds-eye +# view. The output generated by do_dot() is a DOT-based figure (as a +# pdf and an editable svg file) and its source dot code. Nodes are +# components, and edges represent the memory hierarchy: the edges are +# directed, from a master to slave. Initially all nodes are +# generated, and then all edges are added. do_dot should be called +# with the top-most SimObject (namely root but not necessarily), the +# output folder and the output dot source filename. From the given +# node, both processes (node and edge creation) is performed +# recursivly, traversing all children of the given root. # # pydot is required. When missing, no output will be generated. # @@ -70,6 +71,8 @@ def dot_create_nodes(simNode, callgraph): else: label = simNode._name full_path = re.sub('\.', '_', simNode.path()) + # add class name under the label + label = "\"" + label + " \\n: " + simNode.__class__.__name__ + "\"" # each component is a sub-graph (cluster) cluster = dot_create_cluster(simNode, full_path, label) @@ -155,19 +158,28 @@ def dot_create_node(simNode, full_path, label): ) # generate color for nodes -# currently a simple grayscale. placeholder for aesthetic programmers. def dot_gen_color(simNode): + # start off with white + base = (256, 256, 256) + # scale the color based on the depth depth = len(simNode.path().split('.')) - depth = 256 - depth * 16 * 3 - return dot_rgb_to_html(simNode, depth, depth, depth) + # slightly arbitrary, but assume that the depth is less than six + # levels + r, g, b = map(lambda x: x * max(1 - depth / 6.0, 0.3), base) -def dot_rgb_to_html(simNode, r, g, b): + return dot_rgb_to_html(r, g, b) + +def dot_rgb_to_html(r, g, b): return "#%.2x%.2x%.2x" % (r, g, b) def do_dot(root, outdir, dotFilename): if not pydot: return - callgraph = pydot.Dot(graph_type='digraph') + # * use ranksep > 1.0 for for vertical separation between nodes + # especially useful if you need to annotate edges using e.g. visio + # which accepts svg format + # * no need for hoizontal separation as nothing moves horizonally + callgraph = pydot.Dot(graph_type='digraph', ranksep='1.3') dot_create_nodes(root, callgraph) dot_create_edges(root, callgraph) dot_filename = os.path.join(outdir, dotFilename) @@ -175,6 +187,7 @@ def do_dot(root, outdir, dotFilename): try: # dot crashes if the figure is extremely wide. # So avoid terminating simulation unnecessarily + callgraph.write_svg(dot_filename + ".svg") callgraph.write_pdf(dot_filename + ".pdf") except: warn("failed to generate pdf output from %s", dot_filename) |