2012-01-16 12:09:52 -05:00
|
|
|
from itertools import combinations
|
2012-09-09 11:31:35 -04:00
|
|
|
from collections import defaultdict
|
2012-01-28 17:17:44 -05:00
|
|
|
|
2012-03-06 12:33:44 -05:00
|
|
|
from migen.fhdl.structure import *
|
2012-09-09 11:31:35 -04:00
|
|
|
from migen.fhdl.tracer import index_id
|
2012-01-16 12:09:52 -05:00
|
|
|
|
2012-09-09 06:27:32 -04:00
|
|
|
def _bin(sig_iters):
|
2012-09-09 11:31:35 -04:00
|
|
|
# advance by one in the trace of each signal
|
2012-01-19 13:25:04 -05:00
|
|
|
status = []
|
2012-01-19 12:25:25 -05:00
|
|
|
for signal, it in sig_iters:
|
2012-09-09 13:33:55 -04:00
|
|
|
step, last = next(it)
|
|
|
|
status.append((signal, it, step, last))
|
2012-09-09 11:31:35 -04:00
|
|
|
|
|
|
|
# build bins accordingly
|
2012-09-09 13:33:55 -04:00
|
|
|
bins = defaultdict(lambda: defaultdict(list))
|
2012-09-09 11:31:35 -04:00
|
|
|
for signal, it, (stepname, stepidx), last in status:
|
2012-01-19 12:42:43 -05:00
|
|
|
if last:
|
2012-09-09 11:31:35 -04:00
|
|
|
it = None
|
2012-09-09 13:33:55 -04:00
|
|
|
bins[stepname][stepidx].append((signal, it))
|
|
|
|
|
|
|
|
r = []
|
|
|
|
# merge bins when all step indices differ
|
|
|
|
for stepname, stepname_d in bins.items():
|
|
|
|
if all(len(content) == 1 for content in stepname_d.values()):
|
|
|
|
r.append((stepname, [(stepidx, signal, it)
|
|
|
|
for stepidx, stepidx_d in stepname_d.items()
|
|
|
|
for signal, it in stepidx_d]))
|
|
|
|
else:
|
|
|
|
for stepidx, stepidx_d in stepname_d.items():
|
|
|
|
r.append((stepname, [(stepidx, signal, it)
|
|
|
|
for signal, it in stepidx_d]))
|
|
|
|
|
|
|
|
#for stepname, content in r:
|
|
|
|
#print("Bin: " + stepname)
|
|
|
|
#for stepidx, signal, it in content:
|
|
|
|
#print(" stepidx:" + str(stepidx) + " " + str(signal) + " " + str(it))
|
|
|
|
#print("++++++++++")
|
|
|
|
|
|
|
|
return r
|
2012-01-16 12:09:52 -05:00
|
|
|
|
2012-01-19 13:24:43 -05:00
|
|
|
def _sets_disjoint(l):
|
|
|
|
for s1, s2 in combinations(l, 2):
|
|
|
|
if not s1.isdisjoint(s2):
|
|
|
|
return False
|
|
|
|
return True
|
2012-09-09 11:31:35 -04:00
|
|
|
|
|
|
|
# sig_iters contains a list of tuples (signal, iterator on the current trace position)
|
2012-09-09 06:27:32 -04:00
|
|
|
def _r_build_pnd(sig_iters):
|
2012-09-09 11:31:35 -04:00
|
|
|
bins = _bin(sig_iters)
|
|
|
|
|
|
|
|
subnames = {}
|
|
|
|
mentions = defaultdict(list)
|
|
|
|
bins_named = []
|
|
|
|
stepindices = {}
|
|
|
|
|
2012-09-09 13:33:55 -04:00
|
|
|
for stepname, next_steps in bins:
|
2012-09-09 11:31:35 -04:00
|
|
|
bin_content = []
|
|
|
|
for stepidx, signal, it in next_steps:
|
|
|
|
if it is None:
|
|
|
|
mentions[stepname].append(signal)
|
|
|
|
else:
|
|
|
|
bin_content.append((signal, it))
|
|
|
|
stepindices[signal] = stepidx
|
|
|
|
if bin_content:
|
|
|
|
bins_named.append((stepname, _r_build_pnd(bin_content)))
|
|
|
|
|
2012-01-19 12:25:25 -05:00
|
|
|
name_sets = [set(sub_pnd.values()) for prefix, sub_pnd in bins_named]
|
2012-01-19 13:24:43 -05:00
|
|
|
if not _sets_disjoint(name_sets):
|
2012-01-19 12:25:25 -05:00
|
|
|
for prefix, sub_pnd in bins_named:
|
2012-09-09 11:31:35 -04:00
|
|
|
for signal, subname in sub_pnd.items():
|
2012-09-09 13:33:55 -04:00
|
|
|
subname = (prefix, subname)
|
2012-09-09 11:31:35 -04:00
|
|
|
subnames[signal] = subname
|
|
|
|
mentions[subname].append(signal)
|
2012-01-19 12:25:25 -05:00
|
|
|
else:
|
|
|
|
for prefix, sub_pnd in bins_named:
|
2012-09-09 11:31:35 -04:00
|
|
|
for signal, subname in sub_pnd.items():
|
2012-09-09 13:33:55 -04:00
|
|
|
subname = ("", subname)
|
2012-09-09 11:31:35 -04:00
|
|
|
subnames[signal] = subname
|
|
|
|
mentions[subname].append(signal)
|
|
|
|
|
|
|
|
# Sort lists of mentions by step indices
|
|
|
|
for v in mentions.values():
|
|
|
|
v.sort(key=lambda x: stepindices[x])
|
|
|
|
|
|
|
|
r = {}
|
2012-09-09 13:33:55 -04:00
|
|
|
for stepname, next_steps in bins:
|
2012-09-09 11:31:35 -04:00
|
|
|
for stepidx, signal, it in next_steps:
|
|
|
|
if it is None:
|
|
|
|
name = stepname
|
2012-09-09 13:33:55 -04:00
|
|
|
prefix = ""
|
2012-09-09 11:31:35 -04:00
|
|
|
else:
|
2012-09-09 13:33:55 -04:00
|
|
|
prefix = subnames[signal][0]
|
|
|
|
name = subnames[signal][1]
|
|
|
|
mention = mentions[(prefix, name)]
|
|
|
|
if prefix:
|
|
|
|
if len(mention) > 1:
|
|
|
|
r[signal] = prefix + str(index_id(mention, signal)) + "_" + name
|
|
|
|
else:
|
|
|
|
r[signal] = prefix + "_" + name
|
2012-09-09 11:31:35 -04:00
|
|
|
else:
|
2012-09-09 13:33:55 -04:00
|
|
|
if len(mention) > 1:
|
|
|
|
r[signal] = name + str(index_id(mention, signal))
|
|
|
|
else:
|
|
|
|
r[signal] = name
|
2012-09-09 11:31:35 -04:00
|
|
|
|
2012-01-19 12:25:25 -05:00
|
|
|
return r
|
|
|
|
|
2012-01-19 12:42:43 -05:00
|
|
|
def last_flagged(seq):
|
|
|
|
seq = iter(seq)
|
|
|
|
a = next(seq)
|
|
|
|
for b in seq:
|
|
|
|
yield a, False
|
|
|
|
a = b
|
|
|
|
yield a, True
|
|
|
|
|
2012-01-20 16:20:32 -05:00
|
|
|
def build_namespace(signals):
|
2012-01-19 12:42:43 -05:00
|
|
|
sig_iters = [(signal, last_flagged(signal.backtrace))
|
2012-01-20 16:20:32 -05:00
|
|
|
for signal in signals if signal.name_override is None]
|
2012-09-09 06:27:32 -04:00
|
|
|
pnd = _r_build_pnd(sig_iters)
|
2012-01-20 16:20:32 -05:00
|
|
|
ns = Namespace(pnd)
|
|
|
|
# register signals with name_override
|
|
|
|
for signal in signals:
|
|
|
|
if signal.name_override is not None:
|
|
|
|
ns.get_name(signal)
|
|
|
|
return ns
|
2012-01-16 12:09:52 -05:00
|
|
|
|
|
|
|
class Namespace:
|
2012-01-19 12:25:25 -05:00
|
|
|
def __init__(self, pnd):
|
2012-01-16 12:09:52 -05:00
|
|
|
self.counts = {}
|
|
|
|
self.sigs = {}
|
2012-01-19 12:25:25 -05:00
|
|
|
self.pnd = pnd
|
2012-01-16 12:09:52 -05:00
|
|
|
|
|
|
|
def get_name(self, sig):
|
2013-02-22 11:56:35 -05:00
|
|
|
if sig.name_override is not None:
|
|
|
|
sig_name = sig.name_override
|
2012-01-19 12:25:25 -05:00
|
|
|
else:
|
2013-02-22 11:56:35 -05:00
|
|
|
sig_name = self.pnd[sig]
|
2012-01-16 12:09:52 -05:00
|
|
|
try:
|
|
|
|
n = self.sigs[sig]
|
|
|
|
except KeyError:
|
|
|
|
try:
|
|
|
|
n = self.counts[sig_name]
|
|
|
|
except KeyError:
|
|
|
|
n = 0
|
|
|
|
self.sigs[sig] = n
|
|
|
|
self.counts[sig_name] = n + 1
|
2012-01-19 12:25:25 -05:00
|
|
|
if n:
|
|
|
|
return sig_name + "_" + str(n)
|
|
|
|
else:
|
|
|
|
return sig_name
|