fhdl/namer: use execution order indices for variable names as well

This commit is contained in:
Sebastien Bourdeauducq 2012-09-09 17:31:35 +02:00
parent f3e3a3eec7
commit 910c350021
2 changed files with 74 additions and 31 deletions

View file

@ -1,43 +1,80 @@
from itertools import combinations
from collections import defaultdict
from migen.fhdl.structure import *
from migen.fhdl.tracer import index_id
def _bin(sig_iters):
# advance by one in the trace of each signal
status = []
for signal, it in sig_iters:
step, last = next(it)
status.append((signal, it, step, last))
terminals = []
bins = {}
for signal, it, step, last in status:
if it is not None:
step, last = next(it)
status.append((signal, it, step, last))
# build bins accordingly
bins = defaultdict(list)
for signal, it, (stepname, stepidx), last in status:
if last:
terminals.append((step, signal))
else:
if step not in bins:
bins[step] = []
bins[step].append((signal, it))
return terminals, bins
it = None
bins[stepname].append((stepidx, signal, it))
return bins
def _sets_disjoint(l):
for s1, s2 in combinations(l, 2):
if not s1.isdisjoint(s2):
return False
return True
# sig_iters contains a list of tuples (signal, iterator on the current trace position)
def _r_build_pnd(sig_iters):
terminals, bins = _bin(sig_iters)
bins_named = [(k, _r_build_pnd(v)) for k, v in bins.items()]
bins = _bin(sig_iters)
subnames = {}
mentions = defaultdict(list)
bins_named = []
stepindices = {}
for stepname, next_steps in bins.items():
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)))
name_sets = [set(sub_pnd.values()) for prefix, sub_pnd in bins_named]
r = {}
if not _sets_disjoint(name_sets):
for prefix, sub_pnd in bins_named:
for s, n in sub_pnd.items():
r[s] = prefix + "_" + n
for signal, subname in sub_pnd.items():
subname = prefix + "_" + subname
subnames[signal] = subname
mentions[subname].append(signal)
else:
for prefix, sub_pnd in bins_named:
r.update(sub_pnd)
for n, s in terminals:
r[s] = n
for signal, subname in sub_pnd.items():
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 = {}
for stepname, next_steps in bins.items():
for stepidx, signal, it in next_steps:
if it is None:
name = stepname
else:
name = subnames[signal]
if len(mentions[name]) > 1:
r[signal] = name + str(index_id(mentions[name], signal))
else:
r[signal] = name
return r
def last_flagged(seq):

View file

@ -1,5 +1,6 @@
import inspect
from opcode import opname
from collections import defaultdict
def get_var_name(frame):
code = frame.f_code
@ -25,6 +26,7 @@ def get_var_name(frame):
else:
return None
name_to_idx = defaultdict(int)
classname_to_objs = dict()
def index_id(l, obj):
@ -33,14 +35,15 @@ def index_id(l, obj):
return n
raise ValueError
def trace_back(name=None):
def trace_back(varname=None):
l = []
frame = inspect.currentframe().f_back.f_back
while frame is not None:
if name is None:
name = get_var_name(frame)
if name is not None:
l.insert(0, name)
if varname is None:
varname = get_var_name(frame)
if varname is not None:
l.insert(0, (varname, name_to_idx[varname]))
name_to_idx[varname] += 1
try:
obj = frame.f_locals["self"]
@ -50,9 +53,13 @@ def trace_back(name=None):
obj = None
if obj is None:
modules = frame.f_globals["__name__"]
modules = modules.split(".")
objname = modules[len(modules)-1]
if varname is not None:
coname = frame.f_code.co_name
if coname == "<module>":
modules = frame.f_globals["__name__"]
modules = modules.split(".")
coname = modules[len(modules)-1]
l.insert(0, (coname, -1))
else:
classname = obj.__class__.__name__.lower()
try:
@ -66,9 +73,8 @@ def trace_back(name=None):
except ValueError:
idx = len(objs)
objs.append(obj)
objname = classname + str(idx)
l.insert(0, objname)
l.insert(0, (classname, idx))
name = None
varname = None
frame = frame.f_back
return l