mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
record: preserve order
This commit is contained in:
parent
bdcaeb159b
commit
89bf704b2b
4 changed files with 34 additions and 36 deletions
|
@ -1,7 +1,7 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.corelogic.record import *
|
from migen.corelogic.record import *
|
||||||
|
|
||||||
TPL = [
|
L = [
|
||||||
("x", BV(10)),
|
("x", BV(10)),
|
||||||
("y", BV(10)),
|
("y", BV(10)),
|
||||||
("level2", [
|
("level2", [
|
||||||
|
@ -10,10 +10,10 @@ TPL = [
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
|
||||||
myrec = Record(TPL)
|
myrec = Record(L)
|
||||||
print(myrec.flatten())
|
print(myrec.flatten())
|
||||||
s = myrec.subrecord("level2/a", "x")
|
s = myrec.subrecord("level2/a", "x")
|
||||||
print(s.flatten())
|
print(s.flatten())
|
||||||
print(s.level2.template())
|
print(s.level2.layout())
|
||||||
myrec2 = myrec.copy()
|
myrec2 = myrec.copy()
|
||||||
print(myrec2.flatten())
|
print(myrec2.flatten())
|
||||||
|
|
|
@ -2,9 +2,10 @@ from migen.fhdl.structure import *
|
||||||
from migen.fhdl.structure import _make_signal_name
|
from migen.fhdl.structure import _make_signal_name
|
||||||
|
|
||||||
class Record:
|
class Record:
|
||||||
def __init__(self, template, name=None):
|
def __init__(self, layout, name=None):
|
||||||
self.name = name or _make_signal_name()
|
self.name = name or _make_signal_name()
|
||||||
for f in template:
|
self.field_order = []
|
||||||
|
for f in layout:
|
||||||
if isinstance(f, tuple):
|
if isinstance(f, tuple):
|
||||||
if isinstance(f[1], BV):
|
if isinstance(f[1], BV):
|
||||||
setattr(self, f[0], Signal(f[1], self.name + "_" + f[0]))
|
setattr(self, f[0], Signal(f[1], self.name + "_" + f[0]))
|
||||||
|
@ -14,24 +15,26 @@ class Record:
|
||||||
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
|
setattr(self, f[0], Record(f[1], self.name + "_" + f[0]))
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
self.field_order.append(f[0])
|
||||||
else:
|
else:
|
||||||
setattr(self, f, Signal(BV(1), self.name + "_" + f))
|
setattr(self, f, Signal(BV(1), self.name + "_" + f))
|
||||||
|
self.field_order.append(f)
|
||||||
|
|
||||||
def template(self):
|
def layout(self):
|
||||||
l = []
|
l = []
|
||||||
for key in sorted(self.__dict__):
|
for key in self.field_order:
|
||||||
e = self.__dict__[key]
|
e = self.__dict__[key]
|
||||||
if isinstance(e, Signal):
|
if isinstance(e, Signal):
|
||||||
l.append((key, e.bv))
|
l.append((key, e.bv))
|
||||||
elif isinstance(e, Record):
|
elif isinstance(e, Record):
|
||||||
l.append((key, e.template()))
|
l.append((key, e.layout()))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def copy(self, name=None):
|
def copy(self, name=None):
|
||||||
return Record(self.template(), name or _make_signal_name())
|
return Record(self.layout(), name or _make_signal_name())
|
||||||
|
|
||||||
def subrecord(self, *descr):
|
def subrecord(self, *descr):
|
||||||
fields = {}
|
fields = []
|
||||||
for item in descr:
|
for item in descr:
|
||||||
path = item.split('/')
|
path = item.split('/')
|
||||||
last = path.pop()
|
last = path.pop()
|
||||||
|
@ -40,24 +43,19 @@ class Record:
|
||||||
for hop in path:
|
for hop in path:
|
||||||
pos_self = getattr(pos_self, hop)
|
pos_self = getattr(pos_self, hop)
|
||||||
try:
|
try:
|
||||||
pos_fields = fields[hop]
|
lu = list(filter(lambda x: x[0] == hop, pos_fields))
|
||||||
except KeyError:
|
pos_fields = lu[0][1]
|
||||||
pos_fields = fields[hop] = {}
|
except IndexError:
|
||||||
if not isinstance(pos_fields, dict):
|
n = []
|
||||||
|
pos_fields.append((hop, n))
|
||||||
|
pos_fields = n
|
||||||
|
if not isinstance(pos_fields, list):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if last in pos_fields:
|
if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
pos_fields[last] = getattr(pos_self, last)
|
pos_fields.append((last, getattr(pos_self, last)))
|
||||||
def dict_to_list(d):
|
print(fields)
|
||||||
l = []
|
return Record(fields, "subrecord")
|
||||||
for key in d:
|
|
||||||
e = d[key]
|
|
||||||
if isinstance(e, dict):
|
|
||||||
l.append((key, dict_to_list(e)))
|
|
||||||
else:
|
|
||||||
l.append((key, e))
|
|
||||||
return l
|
|
||||||
return Record(dict_to_list(fields), "subrecord")
|
|
||||||
|
|
||||||
def compatible(self, other):
|
def compatible(self, other):
|
||||||
tpl1 = self.flatten()
|
tpl1 = self.flatten()
|
||||||
|
@ -66,7 +64,7 @@ class Record:
|
||||||
|
|
||||||
def flatten(self):
|
def flatten(self):
|
||||||
l = []
|
l = []
|
||||||
for key in sorted(self.__dict__):
|
for key in self.field_order:
|
||||||
e = self.__dict__[key]
|
e = self.__dict__[key]
|
||||||
if isinstance(e, Signal):
|
if isinstance(e, Signal):
|
||||||
l.append(e)
|
l.append(e)
|
||||||
|
@ -75,4 +73,4 @@ class Record:
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.template())
|
return repr(self.layout())
|
||||||
|
|
|
@ -14,7 +14,7 @@ def _simple_binary(a, b, actor_class):
|
||||||
width = max(signal_self.bv.width, signal_other.bv.width)
|
width = max(signal_self.bv.width, signal_other.bv.width)
|
||||||
signed = signal_self.bv.signed and signal_other.bv.signed
|
signed = signal_self.bv.signed and signal_other.bv.signed
|
||||||
actor = actor_class(BV(width, signed))
|
actor = actor_class(BV(width, signed))
|
||||||
combinator = Combinator(actor.operands.template(), ["a"], ["b"])
|
combinator = Combinator(actor.operands.layout(), ["a"], ["b"])
|
||||||
add_connection(a.dfg, combinator, actor)
|
add_connection(a.dfg, combinator, actor)
|
||||||
add_connection(a.dfg, a.actor, combinator, a.endp, combinator.sinks()[0])
|
add_connection(a.dfg, a.actor, combinator, a.endp, combinator.sinks()[0])
|
||||||
add_connection(a.dfg, b.actor, combinator, b.endp, combinator.sinks()[1])
|
add_connection(a.dfg, b.actor, combinator, b.endp, combinator.sinks()[1])
|
||||||
|
|
|
@ -4,9 +4,9 @@ from migen.corelogic.record import *
|
||||||
from migen.corelogic.misc import optree
|
from migen.corelogic.misc import optree
|
||||||
|
|
||||||
class Buffer(Actor):
|
class Buffer(Actor):
|
||||||
def __init__(self, template):
|
def __init__(self, layout):
|
||||||
self.d = Record(template)
|
self.d = Record(layout)
|
||||||
self.q = Record(template)
|
self.q = Record(layout)
|
||||||
Actor.__init__(self,
|
Actor.__init__(self,
|
||||||
SchedulingModel(SchedulingModel.PIPELINE, 1),
|
SchedulingModel(SchedulingModel.PIPELINE, 1),
|
||||||
self.d, self.q)
|
self.d, self.q)
|
||||||
|
@ -18,8 +18,8 @@ class Buffer(Actor):
|
||||||
return Fragment(sync=sync)
|
return Fragment(sync=sync)
|
||||||
|
|
||||||
class Combinator(Actor):
|
class Combinator(Actor):
|
||||||
def __init__(self, template, *subrecords):
|
def __init__(self, layout, *subrecords):
|
||||||
self.destination = Record(template)
|
self.destination = Record(layout)
|
||||||
self.ins = [self.destination.subrecord(*subr) for subr in subrecords]
|
self.ins = [self.destination.subrecord(*subr) for subr in subrecords]
|
||||||
Actor.__init__(self,
|
Actor.__init__(self,
|
||||||
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
|
@ -36,8 +36,8 @@ class Combinator(Actor):
|
||||||
return Fragment(comb)
|
return Fragment(comb)
|
||||||
|
|
||||||
class Splitter(Actor):
|
class Splitter(Actor):
|
||||||
def __init__(self, template, *subrecords):
|
def __init__(self, layout, *subrecords):
|
||||||
self.source = Record(template)
|
self.source = Record(layout)
|
||||||
self.outs = [self.source.subrecord(*subr) for subr in subrecords]
|
self.outs = [self.source.subrecord(*subr) for subr in subrecords]
|
||||||
Actor.__init__(self,
|
Actor.__init__(self,
|
||||||
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
|
|
Loading…
Reference in a new issue