namer: split by numbers
This commit is contained in:
parent
0e369318bb
commit
fd34b75fb4
|
@ -5,20 +5,59 @@ from migen.fhdl.structure import *
|
||||||
|
|
||||||
class _Node:
|
class _Node:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.signal_count = 0
|
||||||
|
self.numbers = set()
|
||||||
self.use_name = False
|
self.use_name = False
|
||||||
|
self.use_number = False
|
||||||
self.children = OrderedDict()
|
self.children = OrderedDict()
|
||||||
|
|
||||||
def _build_tree(signals):
|
def _display_tree(filename, tree):
|
||||||
|
from migen.graph.treeviz import RenderNode
|
||||||
|
|
||||||
|
def _to_render_node(name, node):
|
||||||
|
children = [_to_render_node(k, v) for k, v in node.children.items()]
|
||||||
|
if node.use_name:
|
||||||
|
if node.use_number:
|
||||||
|
color = (0.5, 0.9, 0.8)
|
||||||
|
else:
|
||||||
|
color = (0.8, 0.5, 0.9)
|
||||||
|
else:
|
||||||
|
if node.use_number:
|
||||||
|
color = (0.9, 0.8, 0.5)
|
||||||
|
else:
|
||||||
|
color = (0.8, 0.8, 0.8)
|
||||||
|
label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers)
|
||||||
|
return RenderNode(label, children, color=color)
|
||||||
|
|
||||||
|
top = _to_render_node("top", tree)
|
||||||
|
top.to_svg(filename)
|
||||||
|
|
||||||
|
def _build_tree(signals, basic_tree=None):
|
||||||
root = _Node()
|
root = _Node()
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
|
current_b = basic_tree
|
||||||
current = root
|
current = root
|
||||||
|
current.signal_count += 1
|
||||||
for name, number in signal.backtrace:
|
for name, number in signal.backtrace:
|
||||||
|
if basic_tree is None:
|
||||||
|
use_number = False
|
||||||
|
else:
|
||||||
|
current_b = current_b.children[name]
|
||||||
|
use_number = current_b.use_number
|
||||||
|
if use_number:
|
||||||
|
key = (name, number)
|
||||||
|
else:
|
||||||
|
key = name
|
||||||
try:
|
try:
|
||||||
current = current.children[name]
|
current = current.children[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
new = _Node()
|
new = _Node()
|
||||||
current.children[name] = new
|
current.children[key] = new
|
||||||
current = new
|
current = new
|
||||||
|
current.numbers.add(number)
|
||||||
|
if use_number:
|
||||||
|
current.all_numbers = sorted(current_b.numbers)
|
||||||
|
current.signal_count += 1
|
||||||
return root
|
return root
|
||||||
|
|
||||||
def _set_use_name(node, node_name=""):
|
def _set_use_name(node, node_name=""):
|
||||||
|
@ -40,37 +79,69 @@ def _set_use_name(node, node_name=""):
|
||||||
r |= c_names
|
r |= c_names
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _display_tree(tree):
|
|
||||||
from migen.graph.treeviz import RenderNode
|
|
||||||
|
|
||||||
def _to_render_node(name, node):
|
|
||||||
children = [_to_render_node(k, v) for k, v in node.children.items()]
|
|
||||||
if node.use_name:
|
|
||||||
color = (0.8, 0.5, 0.9)
|
|
||||||
else:
|
|
||||||
color = (0.8, 0.8, 0.8)
|
|
||||||
return RenderNode(name, children, color=color)
|
|
||||||
|
|
||||||
top = _to_render_node("top", tree)
|
|
||||||
top.to_svg("names.svg")
|
|
||||||
|
|
||||||
def _name_signal(tree, signal):
|
def _name_signal(tree, signal):
|
||||||
elements = []
|
elements = []
|
||||||
treepos = tree
|
treepos = tree
|
||||||
for step_name, step_n in signal.backtrace:
|
for step_name, step_n in signal.backtrace:
|
||||||
|
try:
|
||||||
|
treepos = treepos.children[(step_name, step_n)]
|
||||||
|
use_number = True
|
||||||
|
except KeyError:
|
||||||
treepos = treepos.children[step_name]
|
treepos = treepos.children[step_name]
|
||||||
|
use_number = False
|
||||||
if treepos.use_name:
|
if treepos.use_name:
|
||||||
elements.append(step_name)
|
elname = step_name
|
||||||
|
if use_number:
|
||||||
|
elname += str(treepos.all_numbers.index(step_n))
|
||||||
|
elements.append(elname)
|
||||||
return "_".join(elements)
|
return "_".join(elements)
|
||||||
|
|
||||||
def _build_pnd(tree, signals):
|
def _build_pnd(tree, signals):
|
||||||
return dict((signal, _name_signal(tree, signal)) for signal in signals)
|
return dict((signal, _name_signal(tree, signal)) for signal in signals)
|
||||||
|
|
||||||
|
def _list_conflicting_signals(pnd):
|
||||||
|
inv_pnd = dict()
|
||||||
|
for k, v in pnd.items():
|
||||||
|
inv_pnd[v] = inv_pnd.get(v, [])
|
||||||
|
inv_pnd[v].append(k)
|
||||||
|
r = set()
|
||||||
|
for k, v in inv_pnd.items():
|
||||||
|
if len(v) > 1:
|
||||||
|
r.update(v)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def _set_use_number(tree, signals):
|
||||||
|
for signal in signals:
|
||||||
|
current = tree
|
||||||
|
for step_name, step_n in signal.backtrace:
|
||||||
|
current = current.children[step_name]
|
||||||
|
current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1
|
||||||
|
|
||||||
|
_debug = True
|
||||||
|
|
||||||
def build_namespace(signals):
|
def build_namespace(signals):
|
||||||
tree = _build_tree(signals)
|
basic_tree = _build_tree(signals)
|
||||||
_set_use_name(tree)
|
_set_use_name(basic_tree)
|
||||||
_display_tree(tree)
|
if _debug:
|
||||||
pnd = _build_pnd(tree, signals)
|
_display_tree("tree_basic.svg", basic_tree)
|
||||||
|
pnd = _build_pnd(basic_tree, signals)
|
||||||
|
|
||||||
|
# If there are conflicts, try splitting the tree by numbers
|
||||||
|
# on paths taken by conflicting signals.
|
||||||
|
conflicting_signals = _list_conflicting_signals(pnd)
|
||||||
|
if conflicting_signals:
|
||||||
|
_set_use_number(basic_tree, conflicting_signals)
|
||||||
|
if _debug:
|
||||||
|
print("namer: using split-by-number strategy")
|
||||||
|
_display_tree("tree_marked.svg", basic_tree)
|
||||||
|
numbered_tree = _build_tree(signals, basic_tree)
|
||||||
|
_set_use_name(numbered_tree)
|
||||||
|
if _debug:
|
||||||
|
_display_tree("tree_numbered.svg", numbered_tree)
|
||||||
|
pnd = _build_pnd(numbered_tree, signals)
|
||||||
|
else:
|
||||||
|
if _debug:
|
||||||
|
print("namer: using basic strategy")
|
||||||
|
|
||||||
ns = Namespace(pnd)
|
ns = Namespace(pnd)
|
||||||
# register signals with name_override
|
# register signals with name_override
|
||||||
|
|
Loading…
Reference in New Issue