Commit 85491efc authored by Sebastien Bourdeauducq's avatar Sebastien Bourdeauducq
Browse files

wishbone_dma: convert to new endpoint API and fix some bugs

parent 77b3c8e3
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())))
...@@ -6,36 +6,45 @@ from migen.flow.actor import * ...@@ -6,36 +6,45 @@ from migen.flow.actor import *
class Reader(Actor): class Reader(Actor):
def __init__(self, layout): def __init__(self, layout):
self.address = Record([("a", BV(30))])
self.data = Record(layout)
self.bus = wishbone.Master() self.bus = wishbone.Master()
Actor.__init__(self, Actor.__init__(self,
SchedulingModel(SchedulingModel.DYNAMIC), SchedulingModel(SchedulingModel.DYNAMIC),
self.address, self.data) ("address", Sink, [("a", BV(30))]),
("data", Source, layout))
def get_fragment(self): 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 nwords = (length + 31)//32
# Address generator # Address generator
ag_stb = Signal() 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: if nwords > 1:
ag_inc = Signal() 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) address_generator = Fragment(sync=ag_sync)
# Output buffer # Output buffer
ob_reg = Signal(BV(length)) ob_reg = Signal(BV(length))
ob_stbs = Signal(BV(nwords)) ob_stbs = Signal(BV(nwords))
ob_sync = [If(ob_stbs[w], ob_reg[32*w:32*(w+1)].eq(self.bus.dat_i)) ob_sync = []
for w in range(nwords)] 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 = [] ob_comb = []
offset = 0 offset = 0
for s in components: for s in components:
w = s.bv.width w = s.bv.width
if isinstance(s, Signal): 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 offset += w
output_buffer = Fragment(ob_comb, ob_sync) output_buffer = Fragment(ob_comb, ob_sync)
...@@ -55,12 +64,12 @@ class Reader(Actor): ...@@ -55,12 +64,12 @@ class Reader(Actor):
if w == nwords - 1: if w == nwords - 1:
next_state = fsm.STROBE next_state = fsm.STROBE
else: else:
state = getattr(fsm, fetch_states[w+1]) next_state = getattr(fsm, fetch_states[w+1])
fsm.act(state, fsm.act(state,
self.bus.cyc_o.eq(1), self.bus.cyc_o.eq(1),
self.bus.stb_o.eq(1), self.bus.stb_o.eq(1),
ob_stbs[w].eq(1),
If(self.bus.ack_i, If(self.bus.ack_i,
ob_stbs[nwords-w-1].eq(1),
fsm.next_state(next_state) fsm.next_state(next_state)
) )
) )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment