flow: plumbing
This commit is contained in:
parent
8f1bf508ca
commit
588f1a259e
|
@ -1,6 +1,22 @@
|
||||||
from migen.fhdl import verilog
|
from migen.fhdl import verilog
|
||||||
from migen.flow.ala import *
|
from migen.flow.ala import *
|
||||||
|
from migen.flow.plumbing import *
|
||||||
|
|
||||||
act = Divider(32)
|
act = Adder(32)
|
||||||
frag = act.get_control_fragment() + act.get_process_fragment()
|
comb = Combinator(act.operands, ["a"], ["b"])
|
||||||
print(verilog.convert(frag))
|
outbuf = Buffer(act.result.template())
|
||||||
|
frag = get_actor_fragments(act, comb, outbuf)
|
||||||
|
|
||||||
|
stb_a = comb.sinks[0].stb
|
||||||
|
ack_a = comb.sinks[0].ack
|
||||||
|
stb_b = comb.sinks[1].stb
|
||||||
|
ack_b = comb.sinks[1].ack
|
||||||
|
stb_a.name = "stb_a_i"
|
||||||
|
ack_a.name = "ack_a_o"
|
||||||
|
stb_b.name = "stb_b_i"
|
||||||
|
ack_b.name = "stb_b_o"
|
||||||
|
a = comb.ins[0].a
|
||||||
|
b = comb.ins[1].b
|
||||||
|
a.name = "a"
|
||||||
|
b.name = "b"
|
||||||
|
print(verilog.convert(frag, ios={stb_a, ack_a, stb_b, ack_b, a, b}))
|
||||||
|
|
|
@ -104,3 +104,6 @@ class Actor:
|
||||||
|
|
||||||
def get_process_fragment(self):
|
def get_process_fragment(self):
|
||||||
raise NotImplementedError("Actor classes must overload get_process_fragment")
|
raise NotImplementedError("Actor classes must overload get_process_fragment")
|
||||||
|
|
||||||
|
def get_actor_fragments(*actors):
|
||||||
|
return sum([a.get_control_fragment() + a.get_process_fragment() for a in actors], Fragment())
|
||||||
|
|
|
@ -6,7 +6,7 @@ from migen.corelogic import divider
|
||||||
class Adder(Actor):
|
class Adder(Actor):
|
||||||
def __init__(self, width):
|
def __init__(self, width):
|
||||||
self.operands = Record([('a', BV(width)), ('b', BV(width))])
|
self.operands = Record([('a', BV(width)), ('b', BV(width))])
|
||||||
self.result = Record(['sum', BV(width+1)])
|
self.result = Record([('sum', BV(width+1))])
|
||||||
Actor.__init__(self,
|
Actor.__init__(self,
|
||||||
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
self.operands, self.result)
|
self.operands, self.result)
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
from migen.fhdl.structure import *
|
||||||
|
from migen.flow.actor import *
|
||||||
|
from migen.corelogic.record import *
|
||||||
|
from migen.corelogic.misc import optree
|
||||||
|
|
||||||
|
class Buffer(Actor):
|
||||||
|
def __init__(self, template):
|
||||||
|
self.d = Record(template)
|
||||||
|
self.q = Record(template)
|
||||||
|
Actor.__init__(self,
|
||||||
|
SchedulingModel(SchedulingModel.PIPELINE, 1),
|
||||||
|
self.d, self.q)
|
||||||
|
|
||||||
|
def get_process_fragment(self):
|
||||||
|
sigs_d = self.d.flatten()
|
||||||
|
sigs_q = self.q.flatten()
|
||||||
|
sync = [Cat(*sigs_q).eq(Cat(*sigs_d))]
|
||||||
|
return Fragment(sync=sync)
|
||||||
|
|
||||||
|
class Combinator(Actor):
|
||||||
|
def __init__(self, destination, *subrecords):
|
||||||
|
self.ins = [destination.subrecord(*subr) for subr in subrecords]
|
||||||
|
Actor.__init__(self,
|
||||||
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
|
self.ins, destination)
|
||||||
|
|
||||||
|
def get_process_fragment(self):
|
||||||
|
return Fragment() # nothing to do
|
||||||
|
|
||||||
|
def get_control_fragment(self):
|
||||||
|
comb = [self.sources[0].stb.eq(optree('&', [sink.stb for sink in self.sinks]))]
|
||||||
|
comb += [sink.ack.eq(self.sources[0].ack & self.sources[0].stb) for sink in self.sinks]
|
||||||
|
return Fragment(comb)
|
||||||
|
|
||||||
|
class Splitter(Actor):
|
||||||
|
def __init__(self, source, *subrecords):
|
||||||
|
self.outs = [source.subrecord(*subr) for subr in subrecords]
|
||||||
|
Actor.__init__(self,
|
||||||
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
|
source, self.outs)
|
||||||
|
|
||||||
|
def get_process_fragment(self):
|
||||||
|
return Fragment() # nothing to do
|
||||||
|
|
||||||
|
# TODO def get_control_fragment(self):
|
Loading…
Reference in New Issue