summaryrefslogtreecommitdiff
path: root/src/python/m5/util/dot_writer.py
diff options
context:
space:
mode:
authorSascha Bischoff <sascha.bischoff@arm.com>2015-12-15 09:40:56 +0000
committerSascha Bischoff <sascha.bischoff@arm.com>2015-12-15 09:40:56 +0000
commit774350b750a3d34ed55f0846d0cd8f8fc4b3897d (patch)
treefa1df70222e6e34f5b83ec97f590482f844c845a /src/python/m5/util/dot_writer.py
parent38a369c473a8c4b53116806fb50797ab73e7442e (diff)
downloadgem5-774350b750a3d34ed55f0846d0cd8f8fc4b3897d.tar.xz
misc: Add secondary dot output for DVFS domains
This patch adds a secondary dot output file which shows the DVFS domains. This has been done separately for now to avoid cluttering the already existing diagram. Due to the way that the clock domains are assigned to components in gem5, this output must be generated after the C++ objects have been instantiated. This further motivates the need to generate this file separately to the current dot output, and not to replace it entirely.
Diffstat (limited to 'src/python/m5/util/dot_writer.py')
-rw-r--r--src/python/m5/util/dot_writer.py107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/python/m5/util/dot_writer.py b/src/python/m5/util/dot_writer.py
index f54d6a1ab..f0ad15adf 100644
--- a/src/python/m5/util/dot_writer.py
+++ b/src/python/m5/util/dot_writer.py
@@ -35,6 +35,7 @@
#
# Authors: Andreas Hansson
# Uri Wiener
+# Sascha Bischoff
#####################################################################
#
@@ -256,6 +257,96 @@ def dot_gen_colour(simNode, isPort = False):
def dot_rgb_to_html(r, g, b):
return "#%.2x%.2x%.2x" % (r, g, b)
+# We need to create all of the clock domains. We abuse the alpha channel to get
+# the correct domain colouring.
+def dot_add_clk_domain(c_dom, v_dom):
+ label = "\"" + str(c_dom) + "\ :\ " + str(v_dom) + "\""
+ label = re.sub('\.', '_', str(label))
+ full_path = re.sub('\.', '_', str(c_dom))
+ return pydot.Cluster( \
+ full_path, \
+ shape = "Mrecord", \
+ label = label, \
+ style = "\"rounded, filled, dashed\"", \
+ color = "#000000", \
+ fillcolor = "#AFC8AF8F", \
+ fontname = "Arial", \
+ fontsize = "14", \
+ fontcolor = "#000000" \
+ )
+
+def dot_create_dvfs_nodes(simNode, callgraph, domain=None):
+ if isRoot(simNode):
+ label = "root"
+ 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)
+
+ # create nodes per port
+ for port_name in simNode._ports.keys():
+ port = simNode._port_refs.get(port_name, None)
+ if port != None:
+ full_port_name = full_path + "_" + port_name
+ port_node = dot_create_node(simNode, full_port_name, port_name)
+ cluster.add_node(port_node)
+
+ # Dictionary of DVFS domains
+ dvfs_domains = {}
+
+ # recurse to children
+ if simNode._children:
+ for c in simNode._children:
+ child = simNode._children[c]
+ if isSimObjectVector(child):
+ for obj in child:
+ try:
+ c_dom = obj.__getattr__('clk_domain')
+ v_dom = c_dom.__getattr__('voltage_domain')
+ except AttributeError:
+ # Just re-use the domain from above
+ c_dom = domain
+ c_dom.__getattr__('voltage_domain')
+ pass
+
+ if c_dom == domain or c_dom == None:
+ dot_create_dvfs_nodes(obj, cluster, domain)
+ else:
+ if c_dom not in dvfs_domains:
+ dvfs_cluster = dot_add_clk_domain(c_dom, v_dom)
+ dvfs_domains[c_dom] = dvfs_cluster
+ else:
+ dvfs_cluster = dvfs_domains[c_dom]
+ dot_create_dvfs_nodes(obj, dvfs_cluster, c_dom)
+ else:
+ try:
+ c_dom = child.__getattr__('clk_domain')
+ v_dom = c_dom.__getattr__('voltage_domain')
+ except AttributeError:
+ # Just re-use the domain from above
+ c_dom = domain
+ c_dom.__getattr__('voltage_domain')
+ pass
+
+ if c_dom == domain or c_dom == None:
+ dot_create_dvfs_nodes(child, cluster, domain)
+ else:
+ if c_dom not in dvfs_domains:
+ dvfs_cluster = dot_add_clk_domain(c_dom, v_dom)
+ dvfs_domains[c_dom] = dvfs_cluster
+ else:
+ dvfs_cluster = dvfs_domains[c_dom]
+ dot_create_dvfs_nodes(child, dvfs_cluster, c_dom)
+
+ for key in dvfs_domains:
+ cluster.add_subgraph(dvfs_domains[key])
+
+ callgraph.add_subgraph(cluster)
+
def do_dot(root, outdir, dotFilename):
if not pydot:
return
@@ -275,3 +366,19 @@ def do_dot(root, outdir, dotFilename):
callgraph.write_pdf(dot_filename + ".pdf")
except:
warn("failed to generate dot output from %s", dot_filename)
+
+def do_dvfs_dot(root, outdir, dotFilename):
+ if not pydot:
+ return
+ dvfsgraph = pydot.Dot(graph_type='digraph', ranksep='1.3')
+ dot_create_dvfs_nodes(root, dvfsgraph)
+ dot_create_edges(root, dvfsgraph)
+ dot_filename = os.path.join(outdir, dotFilename)
+ dvfsgraph.write(dot_filename)
+ try:
+ # dot crashes if the figure is extremely wide.
+ # So avoid terminating simulation unnecessarily
+ dvfsgraph.write_svg(dot_filename + ".svg")
+ dvfsgraph.write_pdf(dot_filename + ".pdf")
+ except:
+ warn("failed to generate dot output from %s", dot_filename)