#!/usr/bin/python # This is a component of emc2 # Copyright 2007 Jeff Epler # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os import sys import commands import re def to_dot_name(s): return re.sub("[^a-zA-Z0-9_]+", "_", s) def port(s): return s.rsplit(".", 1)[0] def leaf(s): if "." in s: return s.rsplit(".", 1)[1] else: return s def to_leaf_name(s): if "." in s: return to_dot_name(s.rsplit(".", 1)[1]) else: return to_dot_name(s) def to_port_name(s): return to_dot_name(s.rsplit(".", 1)[0]) def to_node_name(s): if "." in s: return "%s:%s" % (to_port_name(s), to_leaf_name(s)) else: n = to_dot_name(s) return "%s:%s" % (n, n) def direction(s): if s in directions: return directions[s] o = commands.getoutput("halcmd -s show pin %s" % s) if "IO" in o: return "both" if "OUT" in o: return 0 if "IN" in o: return 1 return "none" print "digraph net {" print " node [shape=record];" directions = {} nodes = {} edges = set() signals = set() def learn_direction(words): last = None dir = None for word in words: if word.startswith("<") and word.endswith(">"): dir = "both" if last: directions[last] = "both" elif word.startswith("<"): dir = 0 if last: directions[last] = 1 elif word.startswith("="): dir = 1 if last: directions[last] = 0 elif dir is not None: directions[word] = dir dir = None last = word def print_signal(sig): if sig in signals: return signals.add(sig) ns = "sig_" + to_dot_name(sig) print " %s [shape=diamond, label=\"%s\"]" % (ns, sig) def handle_net(words): sig = words[1] print_signal(sig) for pin in words[2:]: handle_linkps(pin, sig) def handle_linkps(pin, sig): print_signal(sig) nw = to_node_name(pin) ns = "sig_" + to_dot_name(sig) pn = port(pin) if pn in nodes: nodes[pn].append(pin) else: nodes[pn] = [pin] d = direction(pin) if d == "both": edges.add((ns, nw, "both",2)) elif d == "none": edges.add((ns, nw, "none",2)) elif d: edges.add((ns, nw, "forward",1)) else: edges.add((nw, ns, "forward",3)) def input(): if len(sys.argv) == 1: for line in os.popen("halcmd save netl"): yield line else: for arg in sys.argv[1:]: if arg == "-": source = sys.stdin else: source = open(arg) for line in source: yield line for line in input(): words = line.split() learn_direction(words) words = [w for w in words if w[0] not in "<="] if not words: continue if words[0] == "net": handle_net(words) elif words[0] == "linkps": handle_linkps(words[1], words[2]) elif words[0] == "linksp": handle_linkps(words[2], words[1]) elif words[0] == "linkpp": handle_linkps(words[1], words[1]) handle_linkps(words[2], words[1]) print for n, v in nodes.items(): label = "|".join("<%s>%s" % (to_leaf_name(i), leaf(i)) for i in sorted(v) if i != n) dn = to_dot_name(n) if label: print " %s [label=\"<%s>%s|%s\"];" % (dn, dn, n, label) else: print " %s [label=\"<%s>%s\"];" % (dn, dn, n) print for a,b,c,d in edges: print " %s -> %s" % (a, b), if c or d: print "[", if c: print "dir=%s" % c, if c and d: print ",", if d: print "weight=%s" % d, print "]", print ";" print "} }"