summaryrefslogtreecommitdiff
path: root/src/python/m5/util
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-09-04 13:22:59 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-09-04 13:22:59 -0400
commitfad36b35c6dc1bfe7406ba15f578b964423a0460 (patch)
treebfb8b86b008c0392c7d176cf0afc076ea2e25047 /src/python/m5/util
parent62cf7851782ad8518ef7881ab1a6d2368dc68afa (diff)
downloadgem5-fad36b35c6dc1bfe7406ba15f578b964423a0460.tar.xz
util: Add colours to the dot output
This patch is adding a splash of colour to the dot output to make it easier to distinguish objects of different types. As a bonus, the pastel-colour palette also makes the output look like a something from the 21st century.
Diffstat (limited to 'src/python/m5/util')
-rw-r--r--src/python/m5/util/dot_writer.py101
1 files changed, 86 insertions, 15 deletions
diff --git a/src/python/m5/util/dot_writer.py b/src/python/m5/util/dot_writer.py
index fbeb655ca..8d93b4263 100644
--- a/src/python/m5/util/dot_writer.py
+++ b/src/python/m5/util/dot_writer.py
@@ -129,43 +129,114 @@ def dot_add_edge(simNode, callgraph, full_port_name, peerPort):
callgraph.add_edge(pydot.Edge(full_port_name, peer_port_name))
def dot_create_cluster(simNode, full_path, label):
- # if you read this, feel free to modify colors / style
return pydot.Cluster( \
full_path, \
shape = "Mrecord", \
label = label, \
style = "\"rounded, filled\"", \
color = "#000000", \
- fillcolor = dot_gen_color(simNode), \
+ fillcolor = dot_gen_colour(simNode), \
fontname = "Arial", \
fontsize = "14", \
fontcolor = "#000000" \
)
def dot_create_node(simNode, full_path, label):
- # if you read this, feel free to modify colors / style.
- # leafs may have a different style => seperate function
return pydot.Node( \
full_path, \
shape = "Mrecord", \
label = label, \
style = "\"rounded, filled\"", \
color = "#000000", \
- fillcolor = "#808080", \
+ fillcolor = dot_gen_colour(simNode, True), \
fontname = "Arial", \
fontsize = "14", \
fontcolor = "#000000" \
)
-# generate color for nodes
-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('.'))
- # 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)
+# an enumerator for different kinds of node types, at the moment we
+# discern the majority of node types, with the caches being the
+# notable exception
+class NodeType:
+ SYS = 0
+ CPU = 1
+ BUS = 2
+ MEM = 3
+ DEV = 4
+ OTHER = 5
+
+# based on the sim object, determine the node type
+def get_node_type(simNode):
+ if isinstance(simNode, m5.objects.System):
+ return NodeType.SYS
+ # NULL ISA has no BaseCPU or PioDevice, so check if these names
+ # exists before using them
+ elif 'BaseCPU' in dir(m5.objects) and \
+ isinstance(simNode, m5.objects.BaseCPU):
+ return NodeType.CPU
+ elif 'PioDevice' in dir(m5.objects) and \
+ isinstance(simNode, m5.objects.PioDevice):
+ return NodeType.DEV
+ elif isinstance(simNode, m5.objects.BaseBus):
+ return NodeType.BUS
+ elif isinstance(simNode, m5.objects.AbstractMemory):
+ return NodeType.MEM
+ else:
+ return NodeType.OTHER
+
+# based on the node type, determine the colour as an RGB tuple, the
+# palette is rather arbitrary at this point (some coherent natural
+# tones), and someone that feels artistic should probably have a look
+def get_type_colour(nodeType):
+ if nodeType == NodeType.SYS:
+ return (228, 231, 235)
+ elif nodeType == NodeType.CPU:
+ return (187, 198, 217)
+ elif nodeType == NodeType.BUS:
+ return (111, 121, 140)
+ elif nodeType == NodeType.MEM:
+ return (94, 89, 88)
+ elif nodeType == NodeType.DEV:
+ return (199, 167, 147)
+ elif nodeType == NodeType.OTHER:
+ # use a relatively gray shade
+ return (186, 182, 174)
+
+# generate colour for a node, either corresponding to a sim object or a
+# port
+def dot_gen_colour(simNode, isPort = False):
+ # determine the type of the current node, and also its parent, if
+ # the node is not the same type as the parent then we use the base
+ # colour for its type
+ node_type = get_node_type(simNode)
+ if simNode._parent:
+ parent_type = get_node_type(simNode._parent)
+ else:
+ parent_type = NodeType.OTHER
+
+ # if this node is the same type as the parent, then scale the
+ # colour based on the depth such that the deeper levels in the
+ # hierarchy get darker colours
+ if node_type == parent_type:
+ # start out with a depth of zero
+ depth = 0
+ parent = simNode._parent
+ # find the closes parent that is not the same type
+ while parent and get_node_type(parent) == parent_type:
+ depth = depth + 1
+ parent = parent._parent
+ node_colour = get_type_colour(parent_type)
+ # slightly arbitrary, but assume that the depth is less than
+ # five levels
+ r, g, b = map(lambda x: x * max(1 - depth / 7.0, 0.3), node_colour)
+ else:
+ node_colour = get_type_colour(node_type)
+ r, g, b = node_colour
+
+ # if we are colouring a port, then make it a slightly darker shade
+ # than the node that encapsulates it, once again use a magic constant
+ if isPort:
+ r, g, b = map(lambda x: 0.8 * x, (r, g, b))
return dot_rgb_to_html(r, g, b)
@@ -190,4 +261,4 @@ def do_dot(root, outdir, dotFilename):
callgraph.write_svg(dot_filename + ".svg")
callgraph.write_pdf(dot_filename + ".pdf")
except:
- warn("failed to generate pdf output from %s", dot_filename)
+ warn("failed to generate dot output from %s", dot_filename)