New naming system: second attempt
This commit is contained in:
parent
a1043d11c0
commit
4eac60d181
|
@ -31,110 +31,92 @@ def trace_back(name=None):
|
||||||
frame = frame.f_back
|
frame = frame.f_back
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def obj_name(obj):
|
class _StepNamer():
|
||||||
if isinstance(obj, str):
|
def __init__(self):
|
||||||
return obj
|
self.name_to_ids = {}
|
||||||
else:
|
|
||||||
return obj.__class__.__name__.lower()
|
|
||||||
|
|
||||||
class TreeNode:
|
|
||||||
def __init__(self, name):
|
|
||||||
self.name = name
|
|
||||||
self.ids = {}
|
|
||||||
self.children = []
|
|
||||||
self.include_context = False
|
|
||||||
self.include_varname = False
|
|
||||||
|
|
||||||
def add_to_tree(root, backtrace):
|
def basename(self, obj):
|
||||||
for step in backtrace:
|
if isinstance(obj, str):
|
||||||
n = obj_name(step[0])
|
return obj
|
||||||
found = list(filter(lambda x: x.name == n, root.children))
|
|
||||||
if found:
|
|
||||||
node = found[0]
|
|
||||||
else:
|
else:
|
||||||
node = TreeNode(n)
|
n = obj.__class__.__name__.lower()
|
||||||
root.children.append(node)
|
try:
|
||||||
if not isinstance(step[0], str) and id(step[0]) not in node.ids:
|
l = self.name_to_ids[n]
|
||||||
node.ids[id(step[0])] = len(node.ids)
|
except KeyError:
|
||||||
root = node
|
self.name_to_ids[n] = [id(obj)]
|
||||||
|
return n + "0"
|
||||||
def build_tree(signals):
|
|
||||||
t = TreeNode("root")
|
|
||||||
for signal in signals:
|
|
||||||
if signal.name_override is None:
|
|
||||||
add_to_tree(t, signal.backtrace)
|
|
||||||
return t
|
|
||||||
|
|
||||||
def name_backtrace(root, backtrace):
|
|
||||||
parts = []
|
|
||||||
for step in backtrace[:-1]:
|
|
||||||
n = obj_name(step[0])
|
|
||||||
found = list(filter(lambda x: x.name == n, root.children))
|
|
||||||
node = found[0]
|
|
||||||
if node.include_context:
|
|
||||||
if len(node.ids) > 1:
|
|
||||||
parts.append(node.name + str(node.ids[id(step[0])]))
|
|
||||||
else:
|
else:
|
||||||
parts.append(node.name)
|
try:
|
||||||
if node.include_varname and step[1] is not None:
|
idx = l.index(id(obj))
|
||||||
parts.append(step[1])
|
except ValueError:
|
||||||
root = node
|
idx = len(l)
|
||||||
last = backtrace[-1]
|
l.append(id(obj))
|
||||||
if last[1] is not None:
|
return n + str(idx)
|
||||||
parts.append(last[1])
|
|
||||||
|
def name(self, step):
|
||||||
|
n = self.basename(step[0])
|
||||||
|
if step[1] is not None:
|
||||||
|
n += "_" + step[1]
|
||||||
|
return n
|
||||||
|
|
||||||
|
def _bin(sn, sig_iters):
|
||||||
|
terminals = []
|
||||||
|
bins = {}
|
||||||
|
for signal, it in sig_iters:
|
||||||
|
try:
|
||||||
|
step = it.__next__()
|
||||||
|
except StopIteration:
|
||||||
|
terminals.append(signal)
|
||||||
|
else:
|
||||||
|
step_name = sn.name(step)
|
||||||
|
if step_name not in bins:
|
||||||
|
bins[step_name] = []
|
||||||
|
bins[step_name].append((signal, it))
|
||||||
|
return terminals, bins
|
||||||
|
|
||||||
|
def _r_build_pnd(sn, sig_iters):
|
||||||
|
terminals, bins = _bin(sn, sig_iters)
|
||||||
|
bins_named = [(k, _r_build_pnd(sn, v)) for k, v in bins.items()]
|
||||||
|
name_sets = [set(sub_pnd.values()) for prefix, sub_pnd in bins_named]
|
||||||
|
if name_sets:
|
||||||
|
intersection = set.intersection(*name_sets)
|
||||||
else:
|
else:
|
||||||
parts.append(obj_name(last[0]))
|
intersection = set()
|
||||||
return "_".join(parts)
|
r = {}
|
||||||
|
if intersection:
|
||||||
def _include_divergence(root, bt1, bt2):
|
for prefix, sub_pnd in bins_named:
|
||||||
for step1, step2 in zip(bt1, bt2):
|
for s, n in sub_pnd.items():
|
||||||
n1, n2 = obj_name(step1[0]), obj_name(step2[0])
|
if n:
|
||||||
node1 = list(filter(lambda x: x.name == n1, root.children))[0]
|
r[s] = prefix + "_" + n
|
||||||
node2 = list(filter(lambda x: x.name == n2, root.children))[0]
|
else:
|
||||||
if node1 != node2:
|
r[s] = prefix
|
||||||
node1.include_context = True
|
|
||||||
node2.include_context = True
|
|
||||||
return
|
|
||||||
if not isinstance(step1[0], str) and not isinstance(step2[0], str) \
|
|
||||||
and id(step1[0]) != id(step2[0]):
|
|
||||||
node1.include_context = True
|
|
||||||
return
|
|
||||||
if step1[1] is not None and step2[1] is not None \
|
|
||||||
and step1[1] != step2[1]:
|
|
||||||
node1.include_varname = True
|
|
||||||
return
|
|
||||||
root = node1
|
|
||||||
|
|
||||||
def resolve_conflicts(root, signals):
|
|
||||||
for s1, s2 in combinations(signals, 2):
|
|
||||||
if name_backtrace(root, s1.backtrace) == name_backtrace(root, s2.backtrace):
|
|
||||||
_include_divergence(root, s1.backtrace, s2.backtrace)
|
|
||||||
|
|
||||||
def build_tree_res(signals):
|
|
||||||
t = build_tree(signals)
|
|
||||||
resolve_conflicts(t, signals)
|
|
||||||
return t
|
|
||||||
|
|
||||||
def signal_name(root, sig):
|
|
||||||
if sig.name_override is not None:
|
|
||||||
return sig.name_override
|
|
||||||
else:
|
else:
|
||||||
return name_backtrace(root, sig.backtrace)
|
for prefix, sub_pnd in bins_named:
|
||||||
|
r.update(sub_pnd)
|
||||||
|
for t in terminals:
|
||||||
|
r[t] = ""
|
||||||
|
return r
|
||||||
|
|
||||||
|
def build_pnd(signals):
|
||||||
|
sig_iters = [(signal, iter(signal.backtrace))
|
||||||
|
for signal in signals]
|
||||||
|
return _r_build_pnd(_StepNamer(), sig_iters)
|
||||||
|
|
||||||
class Namespace:
|
class Namespace:
|
||||||
def __init__(self, tree):
|
def __init__(self, pnd):
|
||||||
self.counts = {}
|
self.counts = {}
|
||||||
self.sigs = {}
|
self.sigs = {}
|
||||||
self.tree = tree
|
self.pnd = pnd
|
||||||
|
|
||||||
def get_name(self, sig):
|
def get_name(self, sig):
|
||||||
sig_name = signal_name(self.tree, sig)
|
if sig.name_override is not None:
|
||||||
|
sig_name = sig.name_override
|
||||||
|
else:
|
||||||
|
sig_name = self.pnd[sig]
|
||||||
|
if not sig_name:
|
||||||
|
sig_name = "anonymous"
|
||||||
try:
|
try:
|
||||||
n = self.sigs[sig]
|
n = self.sigs[sig]
|
||||||
if n:
|
|
||||||
return sig_name + "_" + str(n)
|
|
||||||
else:
|
|
||||||
return sig_name
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
n = self.counts[sig_name]
|
n = self.counts[sig_name]
|
||||||
|
@ -142,7 +124,7 @@ class Namespace:
|
||||||
n = 0
|
n = 0
|
||||||
self.sigs[sig] = n
|
self.sigs[sig] = n
|
||||||
self.counts[sig_name] = n + 1
|
self.counts[sig_name] = n + 1
|
||||||
if n:
|
if n:
|
||||||
return sig_name + "_" + str(n)
|
return sig_name + "_" + str(n)
|
||||||
else:
|
else:
|
||||||
return sig_name
|
return sig_name
|
||||||
|
|
|
@ -3,7 +3,7 @@ from functools import partial
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
|
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
|
||||||
from migen.fhdl.tools import *
|
from migen.fhdl.tools import *
|
||||||
from migen.fhdl.namer import Namespace, build_tree_res
|
from migen.fhdl.namer import Namespace, build_pnd
|
||||||
|
|
||||||
def _printsig(ns, s):
|
def _printsig(ns, s):
|
||||||
if s.bv.signed:
|
if s.bv.signed:
|
||||||
|
@ -213,7 +213,7 @@ def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, return_n
|
||||||
if rst_signal is None:
|
if rst_signal is None:
|
||||||
rst_signal = Signal(name_override="sys_rst")
|
rst_signal = Signal(name_override="sys_rst")
|
||||||
ios.add(rst_signal)
|
ios.add(rst_signal)
|
||||||
ns = Namespace(namer.build_tree_res(list_signals(f)))
|
ns = Namespace(namer.build_pnd(list_signals(f)))
|
||||||
|
|
||||||
ios |= f.pads
|
ios |= f.pads
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue