from migen.fhdl.structure import *
-from migen.fhdl.structure import _make_signal_name
class Record:
def __init__(self, layout, name=None):
- self.name = name or _make_signal_name()
+ self.name = name or "anonymous"
self.field_order = []
for f in layout:
if isinstance(f, tuple):
return l
def copy(self, name=None):
- return Record(self.layout(), name or _make_signal_name())
+ return Record(self.layout(), name)
def get_alignment(self, name):
return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
--- /dev/null
+import inspect
+import re
+from itertools import combinations
+
+class NoContext:
+ pass
+
+def trace_back(name=None):
+ l = []
+ frame = inspect.currentframe().f_back.f_back
+ while frame is not None:
+ try:
+ obj = frame.f_locals["self"]
+ except KeyError:
+ obj = None
+ if obj is None or isinstance(obj, NoContext):
+ modules = frame.f_globals["__name__"]
+ modules = modules.split(".")
+ obj = modules[len(modules)-1]
+
+ if name is None:
+ line = inspect.getframeinfo(frame).code_context[0]
+ m = re.match("[\t ]*([0-9A-Za-z_\.]+)[\t ]*=", line)
+ if m is None:
+ name = None
+ else:
+ names = m.group(1).split(".")
+ name = names[len(names)-1]
+ l.insert(0, (obj, name))
+ name = None
+ frame = frame.f_back
+ return l
+
+def obj_name(obj):
+ if isinstance(obj, str):
+ return obj
+ 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):
+ for step in backtrace:
+ n = obj_name(step[0])
+ found = list(filter(lambda x: x.name == n, root.children))
+ if found:
+ node = found[0]
+ else:
+ node = TreeNode(n)
+ root.children.append(node)
+ if not isinstance(step[0], str) and id(step[0]) not in node.ids:
+ node.ids[id(step[0])] = len(node.ids)
+ root = node
+
+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:
+ 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:
+ parts.append(node.name)
+ if node.include_varname and step[1] is not None:
+ parts.append(step[1])
+ return "_".join(parts)
+
+def _include_divergence(root, bt1, bt2):
+ for step1, step2 in zip(bt1, bt2):
+ n1, n2 = obj_name(step1[0]), obj_name(step2[0])
+ node1 = list(filter(lambda x: x.name == n1, root.children))
+ node2 = list(filter(lambda x: x.name == n2, root.children))
+ if node1 != node2:
+ 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) == name_backtrace(root, s2):
+ _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:
+ return name_backtrace(root, sig.backtrace)
+
+class Namespace:
+ def __init__(self, tree):
+ self.counts = {}
+ self.sigs = {}
+ self.tree = tree
+
+ def get_name(self, sig):
+ sig_name = signal_name(self.tree, sig)
+ try:
+ n = self.sigs[sig]
+ if n:
+ return sig_name + "_" + str(n)
+ else:
+ return sig_name
+ except KeyError:
+ try:
+ n = self.counts[sig_name]
+ except KeyError:
+ n = 0
+ self.sigs[sig] = n
+ self.counts[sig_name] = n + 1
+ if n:
+ return sig_name + "_" + str(n)
+ else:
+ return sig_name
import inspect
import re
+from migen.fhdl import namer
+
def bits_for(n):
if isinstance(n, Constant):
return n.bv.width
else:
return x
-_forbidden_prefixes = {'inst', 'source', 'sink', 'fsm'}
-
-def _try_class_name(frame):
- while frame is not None:
- try:
- cl = frame.f_locals['self']
- prefix = cl.__class__.__name__.lower()
- if prefix not in _forbidden_prefixes:
- return prefix
- except KeyError:
- pass
- frame = frame.f_back
- return None
-
-def _try_module_name(frame):
- modules = frame.f_globals["__name__"]
- if modules != "__main__":
- modules = modules.split('.')
- prefix = modules[len(modules)-1]
- return prefix
- else:
- return None
-
-def _make_signal_name(name=None, back=2):
- frame = inspect.currentframe()
- for i in range(back):
- frame = frame.f_back
-
- if name is None:
- line = inspect.getframeinfo(frame).code_context[0]
- m = re.match('[\t ]*([0-9A-Za-z_\.]+)[\t ]*=', line)
- if m is None:
- name = "anonymous"
- else:
- names = m.group(1).split('.')
- name = names[len(names)-1]
-
- prefix = _try_class_name(frame)
- if prefix is None:
- prefix = _try_module_name(frame)
- if prefix is None:
- prefix = ""
- else:
- prefix += "_"
-
- return prefix + name
-
class Signal(Value):
- def __init__(self, bv=BV(), name=None, variable=False, reset=0, namer=None):
+ def __init__(self, bv=BV(), name=None, variable=False, reset=0, name_override=None):
self.bv = bv
self.variable = variable
- self.name = name
- if self.name is None:
- self.name = _make_signal_name(namer)
self.reset = Constant(reset, bv)
+ self.name_override = name_override
+ self.backtrace = namer.trace_back(name)
def __hash__(self):
return id(self)
from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
-class Namespace:
- def __init__(self):
- self.counts = {}
- self.sigs = {}
-
- def get_name(self, sig):
- try:
- n = self.sigs[sig]
- if n:
- return sig.name + "_" + str(n)
- else:
- return sig.name
- except KeyError:
- try:
- n = self.counts[sig.name]
- except KeyError:
- n = 0
- self.sigs[sig] = n
- self.counts[sig.name] = n + 1
- if n:
- return sig.name + "_" + str(n)
- else:
- return sig.name
-
def list_signals(node):
if node is None:
return set()
from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _StatementList
from migen.fhdl.tools import *
+from migen.fhdl.namer import Namespace, build_tree_res
def _printsig(ns, s):
if s.bv.signed:
r += ");\n\n"
return r
-def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, ns=None):
+def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, return_ns=False):
if clk_signal is None:
- clk_signal = Signal(name="sys_clk")
+ clk_signal = Signal(name_override="sys_clk")
ios.add(clk_signal)
if rst_signal is None:
- rst_signal = Signal(name="sys_rst")
+ rst_signal = Signal(name_override="sys_rst")
ios.add(rst_signal)
- if ns is None:
- ns = Namespace()
+ ns = Namespace(namer.build_tree_res(list_signals(f)))
ios |= f.pads
r += "endmodule\n"
- return r
+ if return_ns:
+ return r, ns
+ else:
+ return r
from migen.fhdl.structure import *
-from migen.fhdl.structure import _make_signal_name
from migen.corelogic.misc import optree
from migen.corelogic.record import *
def __init__(self, token):
self.token = token
if isinstance(self, Sink):
- self.stb = Signal(namer="stb_i")
- self.ack = Signal(namer="ack_o")
+ self.stb = Signal(name="stb_i")
+ self.ack = Signal(name="ack_o")
else:
- self.stb = Signal(namer="stb_o")
- self.ack = Signal(namer="ack_i")
+ self.stb = Signal(name="stb_o")
+ self.ack = Signal(name="ack_i")
def token_signal(self):
sigs = self.token.flatten()
if isinstance(desc[2], Record):
token = desc[2]
else:
- token = Record(desc[2], name=_make_signal_name(desc[0], 1))
+ token = Record(desc[2])
ep = desc[1](token)
self.endpoints[desc[0]] = ep
else: