dot_writer.py (10405:7a618c07e663) dot_writer.py (11418:0aeca8f47eac)
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

--- 21 unchanged lines hidden (view full) ---

30# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35#
36# Authors: Andreas Hansson
37# Uri Wiener
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

--- 21 unchanged lines hidden (view full) ---

30# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35#
36# Authors: Andreas Hansson
37# Uri Wiener
38# Sascha Bischoff
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
45# view. The output generated by do_dot() is a DOT-based figure (as a

--- 205 unchanged lines hidden (view full) ---

251 if isPort:
252 r, g, b = map(lambda x: 0.8 * x, (r, g, b))
253
254 return dot_rgb_to_html(r, g, b)
255
256def dot_rgb_to_html(r, g, b):
257 return "#%.2x%.2x%.2x" % (r, g, b)
258
39
40#####################################################################
41#
42# System visualization using DOT
43#
44# While config.ini and config.json provide an almost complete listing
45# of a system's components and connectivity, they lack a birds-eye
46# view. The output generated by do_dot() is a DOT-based figure (as a

--- 205 unchanged lines hidden (view full) ---

252 if isPort:
253 r, g, b = map(lambda x: 0.8 * x, (r, g, b))
254
255 return dot_rgb_to_html(r, g, b)
256
257def dot_rgb_to_html(r, g, b):
258 return "#%.2x%.2x%.2x" % (r, g, b)
259
260# We need to create all of the clock domains. We abuse the alpha channel to get
261# the correct domain colouring.
262def dot_add_clk_domain(c_dom, v_dom):
263 label = "\"" + str(c_dom) + "\ :\ " + str(v_dom) + "\""
264 label = re.sub('\.', '_', str(label))
265 full_path = re.sub('\.', '_', str(c_dom))
266 return pydot.Cluster( \
267 full_path, \
268 shape = "Mrecord", \
269 label = label, \
270 style = "\"rounded, filled, dashed\"", \
271 color = "#000000", \
272 fillcolor = "#AFC8AF8F", \
273 fontname = "Arial", \
274 fontsize = "14", \
275 fontcolor = "#000000" \
276 )
277
278def dot_create_dvfs_nodes(simNode, callgraph, domain=None):
279 if isRoot(simNode):
280 label = "root"
281 else:
282 label = simNode._name
283 full_path = re.sub('\.', '_', simNode.path())
284 # add class name under the label
285 label = "\"" + label + " \\n: " + simNode.__class__.__name__ + "\""
286
287 # each component is a sub-graph (cluster)
288 cluster = dot_create_cluster(simNode, full_path, label)
289
290 # create nodes per port
291 for port_name in simNode._ports.keys():
292 port = simNode._port_refs.get(port_name, None)
293 if port != None:
294 full_port_name = full_path + "_" + port_name
295 port_node = dot_create_node(simNode, full_port_name, port_name)
296 cluster.add_node(port_node)
297
298 # Dictionary of DVFS domains
299 dvfs_domains = {}
300
301 # recurse to children
302 if simNode._children:
303 for c in simNode._children:
304 child = simNode._children[c]
305 if isSimObjectVector(child):
306 for obj in child:
307 try:
308 c_dom = obj.__getattr__('clk_domain')
309 v_dom = c_dom.__getattr__('voltage_domain')
310 except AttributeError:
311 # Just re-use the domain from above
312 c_dom = domain
313 c_dom.__getattr__('voltage_domain')
314 pass
315
316 if c_dom == domain or c_dom == None:
317 dot_create_dvfs_nodes(obj, cluster, domain)
318 else:
319 if c_dom not in dvfs_domains:
320 dvfs_cluster = dot_add_clk_domain(c_dom, v_dom)
321 dvfs_domains[c_dom] = dvfs_cluster
322 else:
323 dvfs_cluster = dvfs_domains[c_dom]
324 dot_create_dvfs_nodes(obj, dvfs_cluster, c_dom)
325 else:
326 try:
327 c_dom = child.__getattr__('clk_domain')
328 v_dom = c_dom.__getattr__('voltage_domain')
329 except AttributeError:
330 # Just re-use the domain from above
331 c_dom = domain
332 c_dom.__getattr__('voltage_domain')
333 pass
334
335 if c_dom == domain or c_dom == None:
336 dot_create_dvfs_nodes(child, cluster, domain)
337 else:
338 if c_dom not in dvfs_domains:
339 dvfs_cluster = dot_add_clk_domain(c_dom, v_dom)
340 dvfs_domains[c_dom] = dvfs_cluster
341 else:
342 dvfs_cluster = dvfs_domains[c_dom]
343 dot_create_dvfs_nodes(child, dvfs_cluster, c_dom)
344
345 for key in dvfs_domains:
346 cluster.add_subgraph(dvfs_domains[key])
347
348 callgraph.add_subgraph(cluster)
349
259def do_dot(root, outdir, dotFilename):
260 if not pydot:
261 return
262 # * use ranksep > 1.0 for for vertical separation between nodes
263 # especially useful if you need to annotate edges using e.g. visio
264 # which accepts svg format
265 # * no need for hoizontal separation as nothing moves horizonally
266 callgraph = pydot.Dot(graph_type='digraph', ranksep='1.3')
267 dot_create_nodes(root, callgraph)
268 dot_create_edges(root, callgraph)
269 dot_filename = os.path.join(outdir, dotFilename)
270 callgraph.write(dot_filename)
271 try:
272 # dot crashes if the figure is extremely wide.
273 # So avoid terminating simulation unnecessarily
274 callgraph.write_svg(dot_filename + ".svg")
275 callgraph.write_pdf(dot_filename + ".pdf")
276 except:
277 warn("failed to generate dot output from %s", dot_filename)
350def do_dot(root, outdir, dotFilename):
351 if not pydot:
352 return
353 # * use ranksep > 1.0 for for vertical separation between nodes
354 # especially useful if you need to annotate edges using e.g. visio
355 # which accepts svg format
356 # * no need for hoizontal separation as nothing moves horizonally
357 callgraph = pydot.Dot(graph_type='digraph', ranksep='1.3')
358 dot_create_nodes(root, callgraph)
359 dot_create_edges(root, callgraph)
360 dot_filename = os.path.join(outdir, dotFilename)
361 callgraph.write(dot_filename)
362 try:
363 # dot crashes if the figure is extremely wide.
364 # So avoid terminating simulation unnecessarily
365 callgraph.write_svg(dot_filename + ".svg")
366 callgraph.write_pdf(dot_filename + ".pdf")
367 except:
368 warn("failed to generate dot output from %s", dot_filename)
369
370def do_dvfs_dot(root, outdir, dotFilename):
371 if not pydot:
372 return
373 dvfsgraph = pydot.Dot(graph_type='digraph', ranksep='1.3')
374 dot_create_dvfs_nodes(root, dvfsgraph)
375 dot_create_edges(root, dvfsgraph)
376 dot_filename = os.path.join(outdir, dotFilename)
377 dvfsgraph.write(dot_filename)
378 try:
379 # dot crashes if the figure is extremely wide.
380 # So avoid terminating simulation unnecessarily
381 dvfsgraph.write_svg(dot_filename + ".svg")
382 dvfsgraph.write_pdf(dot_filename + ".pdf")
383 except:
384 warn("failed to generate dot output from %s", dot_filename)