From 85491efc68afda03a48aae35a507f97115635053 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 15 Jan 2012 16:41:15 +0100 Subject: [PATCH] wishbone_dma: convert to new endpoint API and fix some bugs --- examples/dataflow_dma.py | 20 ++++++++++++++++++++ migen/actorlib/dma_wishbone.py | 31 ++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 examples/dataflow_dma.py diff --git a/examples/dataflow_dma.py b/examples/dataflow_dma.py new file mode 100644 index 000000000..267176916 --- /dev/null +++ b/examples/dataflow_dma.py @@ -0,0 +1,20 @@ +import sys +import networkx as nx + +from migen.fhdl import verilog +from migen.flow.ala import * +from migen.flow.network import * +from migen.actorlib import dma_wishbone + +L = [ + ("x", BV(10), 8), + ("y", BV(10), 8), + ("level2", [ + ("a", BV(5), 32), + ("b", BV(5), 16) + ]) +] + +reader = dma_wishbone.Reader(L) +frag = reader.get_fragment() +print(verilog.convert(frag, ios=set(reader.bus.signals()))) diff --git a/migen/actorlib/dma_wishbone.py b/migen/actorlib/dma_wishbone.py index c3ad3af1c..3bf3ff8c9 100644 --- a/migen/actorlib/dma_wishbone.py +++ b/migen/actorlib/dma_wishbone.py @@ -6,36 +6,45 @@ from migen.flow.actor import * class Reader(Actor): def __init__(self, layout): - self.address = Record([("a", BV(30))]) - self.data = Record(layout) self.bus = wishbone.Master() Actor.__init__(self, SchedulingModel(SchedulingModel.DYNAMIC), - self.address, self.data) + ("address", Sink, [("a", BV(30))]), + ("data", Source, layout)) def get_fragment(self): - components, length = self.data.flatten(align=True, return_offset=True) + components, length = self.token("data").flatten(align=True, return_offset=True) nwords = (length + 31)//32 # Address generator ag_stb = Signal() - ag_sync = [If(ag_stb, self.bus.adr_o.eq(self.address.a))] + ag_sync = [If(ag_stb, self.bus.adr_o.eq(self.token("address").a))] if nwords > 1: ag_inc = Signal() - sync.append(If(ag_inc, self.bus.adr_o.eq(self.bus.adr_o + 1))) + ag_sync.append(If(ag_inc, self.bus.adr_o.eq(self.bus.adr_o + 1))) address_generator = Fragment(sync=ag_sync) # Output buffer ob_reg = Signal(BV(length)) ob_stbs = Signal(BV(nwords)) - ob_sync = [If(ob_stbs[w], ob_reg[32*w:32*(w+1)].eq(self.bus.dat_i)) - for w in range(nwords)] + ob_sync = [] + top = length + for w in range(nwords): + if top >= 32: + width = 32 + sl = self.bus.dat_i + else: + width = top + sl = self.bus.dat_i[32-top:] + ob_sync.append(If(ob_stbs[w], + ob_reg[top-width:top].eq(sl))) + top -= width ob_comb = [] offset = 0 for s in components: w = s.bv.width if isinstance(s, Signal): - comb.append(s.eq(ob_reg[length-offset-w:length-offset])) + ob_comb.append(s.eq(ob_reg[length-offset-w:length-offset])) offset += w output_buffer = Fragment(ob_comb, ob_sync) @@ -55,12 +64,12 @@ class Reader(Actor): if w == nwords - 1: next_state = fsm.STROBE else: - state = getattr(fsm, fetch_states[w+1]) + next_state = getattr(fsm, fetch_states[w+1]) fsm.act(state, self.bus.cyc_o.eq(1), self.bus.stb_o.eq(1), + ob_stbs[w].eq(1), If(self.bus.ack_i, - ob_stbs[nwords-w-1].eq(1), fsm.next_state(next_state) ) )