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 _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):
|
||||
|
@ -34,7 +33,7 @@ class Record:
|
|||
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]
|
||||
|
|
|
@ -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 re
|
||||
|
||||
from migen.fhdl import namer
|
||||
|
||||
def bits_for(n):
|
||||
if isinstance(n, Constant):
|
||||
return n.bv.width
|
||||
|
@ -131,61 +133,13 @@ def _cst(x):
|
|||
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)
|
||||
|
|
|
@ -1,30 +1,6 @@
|
|||
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()
|
||||
|
|
|
@ -3,6 +3,7 @@ from functools import partial
|
|||
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:
|
||||
|
@ -205,15 +206,14 @@ def _printinstances(ns, i, clk, rst):
|
|||
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
|
||||
|
||||
|
@ -225,4 +225,7 @@ def convert(f, ios=set(), name="top", clk_signal=None, rst_signal=None, ns=None)
|
|||
|
||||
r += "endmodule\n"
|
||||
|
||||
if return_ns:
|
||||
return r, ns
|
||||
else:
|
||||
return r
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.fhdl.structure import _make_signal_name
|
||||
from migen.corelogic.misc import optree
|
||||
from migen.corelogic.record import *
|
||||
|
||||
|
@ -26,11 +25,11 @@ class Endpoint:
|
|||
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()
|
||||
|
@ -108,7 +107,7 @@ class Actor:
|
|||
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:
|
||||
|
|
Loading…
Reference in New Issue