From 588f1a259e425c9d2d4e0483ec9c569347dc177a Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 6 Jan 2012 17:24:05 +0100 Subject: [PATCH] flow: plumbing --- examples/dataflow.py | 22 ++++++++++++++++++--- migen/flow/actor.py | 3 +++ migen/flow/ala.py | 2 +- migen/flow/plumbing.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 migen/flow/plumbing.py diff --git a/examples/dataflow.py b/examples/dataflow.py index 06c2ab123..57035ce33 100644 --- a/examples/dataflow.py +++ b/examples/dataflow.py @@ -1,6 +1,22 @@ from migen.fhdl import verilog from migen.flow.ala import * +from migen.flow.plumbing import * -act = Divider(32) -frag = act.get_control_fragment() + act.get_process_fragment() -print(verilog.convert(frag)) +act = Adder(32) +comb = Combinator(act.operands, ["a"], ["b"]) +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})) diff --git a/migen/flow/actor.py b/migen/flow/actor.py index f1b783a67..98e9ba789 100644 --- a/migen/flow/actor.py +++ b/migen/flow/actor.py @@ -104,3 +104,6 @@ class Actor: def get_process_fragment(self): 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()) diff --git a/migen/flow/ala.py b/migen/flow/ala.py index b3456eb51..1fc53bb34 100644 --- a/migen/flow/ala.py +++ b/migen/flow/ala.py @@ -6,7 +6,7 @@ from migen.corelogic import divider class Adder(Actor): def __init__(self, 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, SchedulingModel(SchedulingModel.COMBINATORIAL), self.operands, self.result) diff --git a/migen/flow/plumbing.py b/migen/flow/plumbing.py new file mode 100644 index 000000000..a3780a159 --- /dev/null +++ b/migen/flow/plumbing.py @@ -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):