mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
wishbone_dma: convert to new endpoint API and fix some bugs
This commit is contained in:
parent
77b3c8e3bb
commit
85491efc68
2 changed files with 40 additions and 11 deletions
20
examples/dataflow_dma.py
Normal file
20
examples/dataflow_dma.py
Normal file
|
@ -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())))
|
|
@ -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):
|
||||||
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)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue