fhdl: new naming system (broken)
This commit is contained in:
parent
e6bfad498d
commit
ab8e08a2ed
|
@ -1,9 +1,8 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl.structure import _make_signal_name
|
|
||||||
|
|
||||||
class Record:
|
class Record:
|
||||||
def __init__(self, layout, name=None):
|
def __init__(self, layout, name=None):
|
||||||
self.name = name or _make_signal_name()
|
self.name = name or "anonymous"
|
||||||
self.field_order = []
|
self.field_order = []
|
||||||
for f in layout:
|
for f in layout:
|
||||||
if isinstance(f, tuple):
|
if isinstance(f, tuple):
|
||||||
|
@ -34,7 +33,7 @@ class Record:
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def copy(self, name=None):
|
def copy(self, name=None):
|
||||||
return Record(self.layout(), name or _make_signal_name())
|
return Record(self.layout(), name)
|
||||||
|
|
||||||
def get_alignment(self, name):
|
def get_alignment(self, name):
|
||||||
return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
|
return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
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
|
|
@ -2,6 +2,8 @@ import math
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from migen.fhdl import namer
|
||||||
|
|
||||||
def bits_for(n):
|
def bits_for(n):
|
||||||
if isinstance(n, Constant):
|
if isinstance(n, Constant):
|
||||||
return n.bv.width
|
return n.bv.width
|
||||||
|
@ -131,61 +133,13 @@ def _cst(x):
|
||||||
else:
|
else:
|
||||||
return x
|
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):
|
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.bv = bv
|
||||||
self.variable = variable
|
self.variable = variable
|
||||||
self.name = name
|
|
||||||
if self.name is None:
|
|
||||||
self.name = _make_signal_name(namer)
|
|
||||||
self.reset = Constant(reset, bv)
|
self.reset = Constant(reset, bv)
|
||||||
|
self.name_override = name_override
|
||||||
|
self.backtrace = namer.trace_back(name)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return id(self)
|
return id(self)
|
||||||
|
|
|
@ -1,30 +1,6 @@
|
||||||
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
|
||||||
|
|
||||||
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):
|
def list_signals(node):
|
||||||
if node is None:
|
if node is None:
|
||||||
return set()
|
return set()
|
||||||
|
|
|
@ -3,6 +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
|
||||||
|
|
||||||
def _printsig(ns, s):
|
def _printsig(ns, s):
|
||||||
if s.bv.signed:
|
if s.bv.signed:
|
||||||
|
@ -205,15 +206,14 @@ def _printinstances(ns, i, clk, rst):
|
||||||
r += ");\n\n"
|
r += ");\n\n"
|
||||||
return r
|
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:
|
if clk_signal is None:
|
||||||
clk_signal = Signal(name="sys_clk")
|
clk_signal = Signal(name_override="sys_clk")
|
||||||
ios.add(clk_signal)
|
ios.add(clk_signal)
|
||||||
if rst_signal is None:
|
if rst_signal is None:
|
||||||
rst_signal = Signal(name="sys_rst")
|
rst_signal = Signal(name_override="sys_rst")
|
||||||
ios.add(rst_signal)
|
ios.add(rst_signal)
|
||||||
if ns is None:
|
ns = Namespace(namer.build_tree_res(list_signals(f)))
|
||||||
ns = Namespace()
|
|
||||||
|
|
||||||
ios |= f.pads
|
ios |= f.pads
|
||||||
|
|
||||||
|
@ -225,4 +225,7 @@ def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, ns=None)
|
||||||
|
|
||||||
r += "endmodule\n"
|
r += "endmodule\n"
|
||||||
|
|
||||||
return r
|
if return_ns:
|
||||||
|
return r, ns
|
||||||
|
else:
|
||||||
|
return r
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl.structure import _make_signal_name
|
|
||||||
from migen.corelogic.misc import optree
|
from migen.corelogic.misc import optree
|
||||||
from migen.corelogic.record import *
|
from migen.corelogic.record import *
|
||||||
|
|
||||||
|
@ -26,11 +25,11 @@ class Endpoint:
|
||||||
def __init__(self, token):
|
def __init__(self, token):
|
||||||
self.token = token
|
self.token = token
|
||||||
if isinstance(self, Sink):
|
if isinstance(self, Sink):
|
||||||
self.stb = Signal(namer="stb_i")
|
self.stb = Signal(name="stb_i")
|
||||||
self.ack = Signal(namer="ack_o")
|
self.ack = Signal(name="ack_o")
|
||||||
else:
|
else:
|
||||||
self.stb = Signal(namer="stb_o")
|
self.stb = Signal(name="stb_o")
|
||||||
self.ack = Signal(namer="ack_i")
|
self.ack = Signal(name="ack_i")
|
||||||
|
|
||||||
def token_signal(self):
|
def token_signal(self):
|
||||||
sigs = self.token.flatten()
|
sigs = self.token.flatten()
|
||||||
|
@ -108,7 +107,7 @@ class Actor:
|
||||||
if isinstance(desc[2], Record):
|
if isinstance(desc[2], Record):
|
||||||
token = desc[2]
|
token = desc[2]
|
||||||
else:
|
else:
|
||||||
token = Record(desc[2], name=_make_signal_name(desc[0], 1))
|
token = Record(desc[2])
|
||||||
ep = desc[1](token)
|
ep = desc[1](token)
|
||||||
self.endpoints[desc[0]] = ep
|
self.endpoints[desc[0]] = ep
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue