Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
actorlib: LASMI DMA (untested)
  • Loading branch information
Sebastien Bourdeauducq committed Jun 10, 2013
1 parent 932bfa7 commit 3a284b9
Showing 1 changed file with 107 additions and 0 deletions.
107 changes: 107 additions & 0 deletions migen/actorlib/dma_lasmi.py
@@ -0,0 +1,107 @@
from migen.fhdl.std import *
from migen.flow.actor import *
from migen.genlib.fifo import SyncFIFO

class Reader(Module):
def __init__(self, lasmim, fifo_depth=None):
self.address = Sink([("a", lasmim.aw)])
self.data = Source([("d", lasmim.dw)])
self.busy = Signal()

###

if fifo_depth is None:
fifo_depth = lasmim.read_latency + 2
assert(fifo_depth >= lasmim.read_latency)

# request issuance
request_enable = Signal()
request_issued = Signal()

self.comb += [
self.bus.we.eq(0),
lasmim.stb.eq(self.address.stb & request_enable),
lasmim.adr.eq(self.address.payload.a),
self.address.ack.eq(lasmim.ack),
request_issued.eq(lasmim.stb & lasmim.ack)
]

# FIFO reservation level counter
# incremented when data is planned to be queued
# decremented when data is dequeued
data_dequeued = Signal()
rsv_level = Signal(max=fifo_depth+1)
self.sync += [
If(request_issued,
If(~data_dequeued, rsv_level.eq(rsv_level + 1))
).Elif(data_dequeued,
rsv_level.eq(rsv_level - 1)
)
]
self.comb += [
self.busy.eq(rsv_level != 0),
request_enable.eq(rsv_level != fifo_depth)
]

# data available
data_available = request_issued
for i in range(lasmim.read_latency):
new_data_available = Signal()
self.sync += new_data_available.eq(data_available)
data_available = new_data_available

# FIFO
fifo = SyncFIFO(lasmim.dw, fifo_depth)
self.submodules += fifo

self.comb += [
fifo.din.eq(lasmim.dat_r),
fifo.we.eq(data_available),

self.data.stb.eq(fifo.readable),
fifo.re.eq(self.data.ack),
self.data.payload.d.eq(fifo.dout),
data_dequeued.eq(self.data.stb & self.data.ack)
]


class Writer(Module):
def __init__(self, lasmim):
self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
self.busy = Signal()

###

self.comb += [
lasmim.we.eq(1),
lasmim.stb.eq(self.address_data.stb),
lasmim.adr.eq(self.address_data.payload.a),
self.address_data.ack.eq(lasmim.ack)
]

busy_expr = 0
data_valid = Signal()
data = Signal(lasmim.dw)
self.comb += [
data_valid.eq(lasmim.stb & lasmim.ack),
data.eq(self.address_data.payload.d)
]

for i in range(lasmim.write_latency):
new_data_valid = Signal()
new_data = Signal(lasmim.dw)
self.sync += [
new_data_valid.eq(data_valid),
new_data.eq(data)
]
busy_expr = busy_expr | new_data_valid
data_valid = new_data_valid
data = new_data

self.comb += [
If(data_valid,
lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
lasmim.dat_w.eq(data)
),
self.busy.eq(busy_expr)
]

0 comments on commit 3a284b9

Please sign in to comment.