#
# Authors: Andreas Hansson
# Uri Wiener
+# Sascha Bischoff
#####################################################################
#
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
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)