106 行
3.3 KiB
Python
106 行
3.3 KiB
Python
from migen import *
|
|
from migen_axi.interconnect import axi
|
|
from misoc.interconnect.csr import *
|
|
from operator import attrgetter
|
|
|
|
|
|
class HP_DMA_READ(Module, AutoCSR):
|
|
def __init__(self, bus=None):
|
|
self.bus = bus or axi.Interface(data_width=64)
|
|
|
|
self.addr_base = CSRStorage(32)
|
|
self.n_bursts = CSRStorage(32) # Number of bursts to do -1
|
|
self.trigger = CSR(1)
|
|
|
|
self.n_cycles = CSRStatus(32)
|
|
self.status = CSRStatus(1)
|
|
self.n_read = CSRStatus(32)
|
|
|
|
self.dout = Signal(32)
|
|
self.dout_stb = Signal()
|
|
|
|
###
|
|
ar, aw, w, r, b = attrgetter("ar", "aw", "w", "r", "b")(self.bus)
|
|
BURST_LEN = 16
|
|
|
|
trigger_stb = self.trigger.re
|
|
addr = Signal(32)
|
|
read_request_accepted = Signal() # Asserted when the read request has been accepted
|
|
read_request = Signal()
|
|
n_done = Signal(32)
|
|
|
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
|
fsm.act("IDLE",
|
|
If(trigger_stb,
|
|
NextValue(addr, self.addr_base.storage),
|
|
NextValue(read_request, 1),
|
|
NextState("RUNNING")
|
|
)
|
|
)
|
|
fsm.act("RUNNING",
|
|
If(read_request_accepted,
|
|
NextValue(addr, addr+BURST_LEN),
|
|
NextValue(n_done, n_done+1),
|
|
If(n_done == self.n_bursts.storage,
|
|
NextState("IDLE"),
|
|
NextValue(read_request, 0)
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
### Read
|
|
self.comb += [
|
|
ar.addr.eq(self.addr_base.storage),
|
|
self.dout.eq(r.data),
|
|
r.ready.eq(1),
|
|
ar.burst.eq(axi.Burst.incr.value),
|
|
ar.len.eq(BURST_LEN-1), # Number of transfers in burst (0->1 transfer, 1->2 transfers...)
|
|
ar.size.eq(3), # Width of burst: 3 = 8 bytes = 64 bits
|
|
ar.cache.eq(0xf),
|
|
]
|
|
|
|
# read control
|
|
self.comb += read_request_accepted.eq(ar.ready & ar.valid)
|
|
self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE")
|
|
read_fsm.act("IDLE",
|
|
If(read_request,
|
|
ar.valid.eq(1),
|
|
If(ar.ready,
|
|
NextState("WAIT")
|
|
).Else(
|
|
NextState("READ_START")
|
|
)
|
|
)
|
|
)
|
|
read_fsm.act("READ_START",
|
|
ar.valid.eq(1),
|
|
If(ar.ready,
|
|
NextState("WAIT"),
|
|
)
|
|
)
|
|
read_fsm.act("WAIT",
|
|
NextState("IDLE")
|
|
)
|
|
|
|
self.comb += self.dout_stb.eq(r.valid & r.ready)
|
|
|
|
n_bursts_received = Signal(32)
|
|
self.sync += [
|
|
If(trigger_stb, n_bursts_received.eq(0)),
|
|
If(self.dout_stb & r.last, n_bursts_received.eq(n_bursts_received+1))
|
|
]
|
|
|
|
self.sync += [
|
|
If(trigger_stb, self.status.status.eq(1)),
|
|
If(n_bursts_received==self.n_bursts.storage+1, self.status.status.eq(0))
|
|
]
|
|
self.sync += [
|
|
If(self.status.status, self.n_cycles.status.eq(self.n_cycles.status+1)),
|
|
If(trigger_stb, self.n_cycles.status.eq(0))
|
|
]
|
|
|
|
self.sync += [
|
|
If(self.dout_stb, self.n_read.status.eq(self.n_read.status+1)),
|
|
If(trigger_stb, self.n_read.status.eq(0))
|
|
] |