dot_writer.py (9528:d05714c2ab9c) | dot_writer.py (9852:16046705aa55) |
---|---|
1# Copyright (c) 2012 ARM Limited | 1# Copyright (c) 2012-2013 ARM Limited |
2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 26 unchanged lines hidden (view full) --- 36# Authors: Andreas Hansson 37# Uri Wiener 38 39##################################################################### 40# 41# System visualization using DOT 42# 43# While config.ini and config.json provide an almost complete listing | 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 26 unchanged lines hidden (view full) --- 36# Authors: Andreas Hansson 37# Uri Wiener 38 39##################################################################### 40# 41# System visualization using DOT 42# 43# While config.ini and config.json provide an almost complete listing |
44# of a system's components and connectivity, they lack a birds-eye view. 45# The output generated by do_dot() is a DOT-based figure (pdf) and its 46# source dot code. Nodes are components, and edges represent 47# the memory hierarchy: the edges are directed, from a master to a slave. 48# Initially all nodes are generated, and then all edges are added. 49# do_dot should be called with the top-most SimObject (namely root 50# but not necessarily), the output folder and the output dot source 51# filename. From the given node, both processes (node and edge creation) 52# is performed recursivly, traversing all children of the given root. | 44# of a system's components and connectivity, they lack a birds-eye 45# view. The output generated by do_dot() is a DOT-based figure (as a 46# pdf and an editable svg file) and its source dot code. Nodes are 47# components, and edges represent the memory hierarchy: the edges are 48# directed, from a master to slave. Initially all nodes are 49# generated, and then all edges are added. do_dot should be called 50# with the top-most SimObject (namely root but not necessarily), the 51# output folder and the output dot source filename. From the given 52# node, both processes (node and edge creation) is performed 53# recursivly, traversing all children of the given root. |
53# 54# pydot is required. When missing, no output will be generated. 55# 56##################################################################### 57 58import m5, os, re 59from m5.SimObject import isRoot, isSimObjectVector 60from m5.util import warn --- 4 unchanged lines hidden (view full) --- 65 66# need to create all nodes (components) before creating edges (memory channels) 67def dot_create_nodes(simNode, callgraph): 68 if isRoot(simNode): 69 label = "root" 70 else: 71 label = simNode._name 72 full_path = re.sub('\.', '_', simNode.path()) | 54# 55# pydot is required. When missing, no output will be generated. 56# 57##################################################################### 58 59import m5, os, re 60from m5.SimObject import isRoot, isSimObjectVector 61from m5.util import warn --- 4 unchanged lines hidden (view full) --- 66 67# need to create all nodes (components) before creating edges (memory channels) 68def dot_create_nodes(simNode, callgraph): 69 if isRoot(simNode): 70 label = "root" 71 else: 72 label = simNode._name 73 full_path = re.sub('\.', '_', simNode.path()) |
74 # add class name under the label 75 label = "\"" + label + " \\n: " + simNode.__class__.__name__ + "\"" |
|
73 74 # each component is a sub-graph (cluster) 75 cluster = dot_create_cluster(simNode, full_path, label) 76 77 # create nodes per port 78 for port_name in simNode._ports.keys(): 79 port = simNode._port_refs.get(port_name, None) 80 if port != None: --- 69 unchanged lines hidden (view full) --- 150 color = "#000000", \ 151 fillcolor = "#808080", \ 152 fontname = "Arial", \ 153 fontsize = "14", \ 154 fontcolor = "#000000" \ 155 ) 156 157# generate color for nodes | 76 77 # each component is a sub-graph (cluster) 78 cluster = dot_create_cluster(simNode, full_path, label) 79 80 # create nodes per port 81 for port_name in simNode._ports.keys(): 82 port = simNode._port_refs.get(port_name, None) 83 if port != None: --- 69 unchanged lines hidden (view full) --- 153 color = "#000000", \ 154 fillcolor = "#808080", \ 155 fontname = "Arial", \ 156 fontsize = "14", \ 157 fontcolor = "#000000" \ 158 ) 159 160# generate color for nodes |
158# currently a simple grayscale. placeholder for aesthetic programmers. | |
159def dot_gen_color(simNode): | 161def dot_gen_color(simNode): |
162 # start off with white 163 base = (256, 256, 256) 164 # scale the color based on the depth |
|
160 depth = len(simNode.path().split('.')) | 165 depth = len(simNode.path().split('.')) |
161 depth = 256 - depth * 16 * 3 162 return dot_rgb_to_html(simNode, depth, depth, depth) | 166 # slightly arbitrary, but assume that the depth is less than six 167 # levels 168 r, g, b = map(lambda x: x * max(1 - depth / 6.0, 0.3), base) |
163 | 169 |
164def dot_rgb_to_html(simNode, r, g, b): | 170 return dot_rgb_to_html(r, g, b) 171 172def dot_rgb_to_html(r, g, b): |
165 return "#%.2x%.2x%.2x" % (r, g, b) 166 167def do_dot(root, outdir, dotFilename): 168 if not pydot: 169 return | 173 return "#%.2x%.2x%.2x" % (r, g, b) 174 175def do_dot(root, outdir, dotFilename): 176 if not pydot: 177 return |
170 callgraph = pydot.Dot(graph_type='digraph') | 178 # * use ranksep > 1.0 for for vertical separation between nodes 179 # especially useful if you need to annotate edges using e.g. visio 180 # which accepts svg format 181 # * no need for hoizontal separation as nothing moves horizonally 182 callgraph = pydot.Dot(graph_type='digraph', ranksep='1.3') |
171 dot_create_nodes(root, callgraph) 172 dot_create_edges(root, callgraph) 173 dot_filename = os.path.join(outdir, dotFilename) 174 callgraph.write(dot_filename) 175 try: 176 # dot crashes if the figure is extremely wide. 177 # So avoid terminating simulation unnecessarily | 183 dot_create_nodes(root, callgraph) 184 dot_create_edges(root, callgraph) 185 dot_filename = os.path.join(outdir, dotFilename) 186 callgraph.write(dot_filename) 187 try: 188 # dot crashes if the figure is extremely wide. 189 # So avoid terminating simulation unnecessarily |
190 callgraph.write_svg(dot_filename + ".svg") |
|
178 callgraph.write_pdf(dot_filename + ".pdf") 179 except: 180 warn("failed to generate pdf output from %s", dot_filename) | 191 callgraph.write_pdf(dot_filename + ".pdf") 192 except: 193 warn("failed to generate pdf output from %s", dot_filename) |