From 910c350021d8480f2b62963a08e586963dca8182 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 9 Sep 2012 17:31:35 +0200 Subject: [PATCH] fhdl/namer: use execution order indices for variable names as well --- migen/fhdl/namer.py | 77 ++++++++++++++++++++++++++++++++------------ migen/fhdl/tracer.py | 28 +++++++++------- 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/migen/fhdl/namer.py b/migen/fhdl/namer.py index e274e3c9..9d32a9ad 100644 --- a/migen/fhdl/namer.py +++ b/migen/fhdl/namer.py @@ -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): diff --git a/migen/fhdl/tracer.py b/migen/fhdl/tracer.py index 03051315..765dea8f 100644 --- a/migen/fhdl/tracer.py +++ b/migen/fhdl/tracer.py @@ -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 == "": + 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 -- 2.30.2