mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
bfm: dma_skeleton
This commit is contained in:
parent
66ef7950ab
commit
eb226c1ade
4 changed files with 78 additions and 12 deletions
|
@ -110,8 +110,15 @@ class SATACommandRX(Module):
|
|||
|
||||
self.comb += [
|
||||
transport.source.ack.eq(1),
|
||||
# XXX for test
|
||||
If(transport.source.stb & (transport.source.type == fis_types["DMA_ACTIVATE_D2H"]),
|
||||
self.to_tx.dma_activate.eq(1)
|
||||
),
|
||||
If(transport.source.stb & (transport.source.type == fis_types["DATA"]),
|
||||
source.stb.eq(1),
|
||||
source.sop.eq(transport.source.sop),
|
||||
source.eop.eq(transport.source.eop),
|
||||
source.data.eq(transport.source.data),
|
||||
)
|
||||
]
|
||||
|
||||
|
|
|
@ -385,13 +385,50 @@ class CommandLayer(Module):
|
|||
self.debug = debug
|
||||
self.transport.set_command_callback(self.callback)
|
||||
|
||||
self.dma_enable = 0
|
||||
self.dma_address = 0
|
||||
|
||||
def allocate_dma(self, base, length):
|
||||
self.dma_base = base
|
||||
self.dma_buffer = [0]*(length//4)
|
||||
|
||||
def enable_dma(self):
|
||||
self.dma_enable = 1
|
||||
|
||||
def disable_dma(self):
|
||||
self.dma_enable = 0
|
||||
|
||||
def dma_write(self, adr, data):
|
||||
current_adr = (adr-self.dma_base)//4
|
||||
for i in range(len(data)):
|
||||
self.dma_buffer[current_adr+i] = data[i]
|
||||
|
||||
def dma_read(self, adr, length=1):
|
||||
current_adr = (adr-self.dma_base)//4
|
||||
data = []
|
||||
for i in range(length//4):
|
||||
data.append(self.dma_buffer[current_adr+i])
|
||||
return data
|
||||
|
||||
def callback(self, fis):
|
||||
# XXX maximum of 2048 DWORDS per DMA
|
||||
if isinstance(fis, FIS_REG_H2D):
|
||||
if fis.command == regs["WRITE_DMA_EXT"]:
|
||||
# XXX add checks
|
||||
self.dma_address = fis.lba_lsb
|
||||
dma_activate = FIS_DMA_ACTIVATE_D2H()
|
||||
# XXX fill dma_activate
|
||||
self.transport.send(dma_activate)
|
||||
elif fis.command == regs["READ_DMA_EXT"]:
|
||||
self.dma_address = fis.lba_lsb
|
||||
data = FIS_DATA(self.dma_read(fis.lba_lsb, fis.count*4))
|
||||
self.transport.send(data)
|
||||
elif fis.command == regs["IDENTIFY_DEVICE_DMA"]:
|
||||
self.dma_address = fis.lba_lsb
|
||||
data = FIS_DATA(self.dma_read(fis.lba_lsb, fis.count*4))
|
||||
self.transport.send(data)
|
||||
elif isinstance(fis, FIS_DATA):
|
||||
if self.dma_enable:
|
||||
self.dma_write(self.dma_address, fis.packet[1:])
|
||||
self.dma_address += len(fis.packet[1:])
|
||||
|
||||
class BFM(Module):
|
||||
def __init__(self,
|
||||
|
|
|
@ -21,6 +21,8 @@ class TB(Module):
|
|||
self.submodules.command = SATACommand(self.transport)
|
||||
|
||||
def gen_simulation(self, selfp):
|
||||
self.bfm.command.allocate_dma(0x00000000, 64*1024*1024)
|
||||
self.bfm.command.enable_dma()
|
||||
for i in range(100):
|
||||
yield
|
||||
for i in range(32):
|
||||
|
@ -28,13 +30,33 @@ class TB(Module):
|
|||
selfp.command.sink.sop = (i==0)
|
||||
selfp.command.sink.eop = (i==31)
|
||||
selfp.command.sink.write = 1
|
||||
selfp.command.sink.address = 0x1234
|
||||
selfp.command.sink.address = 1024
|
||||
selfp.command.sink.length = 32
|
||||
selfp.command.sink.data = i
|
||||
yield
|
||||
while selfp.command.sink.ack == 0:
|
||||
yield
|
||||
selfp.command.sink.ack = 0
|
||||
selfp.command.sink.stb = 0
|
||||
for i in range(32):
|
||||
yield
|
||||
selfp.command.sink.stb = 1
|
||||
selfp.command.sink.sop = 1
|
||||
selfp.command.sink.eop = 1
|
||||
selfp.command.sink.write = 0
|
||||
selfp.command.sink.read = 1
|
||||
selfp.command.sink.address = 1024
|
||||
selfp.command.sink.length = 32
|
||||
yield
|
||||
while selfp.command.sink.ack == 0:
|
||||
yield
|
||||
selfp.command.sink.stb = 0
|
||||
while True:
|
||||
if selfp.command.source.stb:
|
||||
print("%08x" %selfp.command.source.data)
|
||||
yield
|
||||
#dma_dump = self.bfm.command.dma_read(1024, 32*4)
|
||||
#for d in dma_dump:
|
||||
# print("%08x" %d)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_simulation(TB(), ncycles=512, vcd_name="my.vcd", keep_files=True)
|
||||
|
|
|
@ -60,7 +60,7 @@ class SATATransportTX(Module):
|
|||
)
|
||||
fsm.act("SEND_REG_H2D_CMD",
|
||||
_encode_cmd(sink, fis_reg_h2d_layout, encoded_cmd),
|
||||
cmd_len.eq(fis_reg_h2d_cmd_len),
|
||||
cmd_len.eq(fis_reg_h2d_cmd_len-1),
|
||||
cmd_send.eq(1),
|
||||
If(cmd_done,
|
||||
sink.ack.eq(1),
|
||||
|
@ -69,7 +69,7 @@ class SATATransportTX(Module):
|
|||
)
|
||||
fsm.act("SEND_DATA_CMD",
|
||||
_encode_cmd(sink, fis_data_layout, encoded_cmd),
|
||||
cmd_len.eq(fis_data_cmd_len),
|
||||
cmd_len.eq(fis_data_cmd_len-1),
|
||||
cmd_with_data.eq(1),
|
||||
cmd_send.eq(1),
|
||||
If(cmd_done,
|
||||
|
@ -84,7 +84,6 @@ class SATATransportTX(Module):
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
cmd_cases = {}
|
||||
for i in range(cmd_ndwords):
|
||||
cmd_cases[i] = [link.sink.d.eq(encoded_cmd[32*i:32*(i+1)])]
|
||||
|
@ -96,7 +95,7 @@ class SATATransportTX(Module):
|
|||
link.sink.eop.eq((cnt==cmd_len) & ~cmd_with_data),
|
||||
Case(cnt, cmd_cases),
|
||||
inc_cnt.eq(link.sink.ack),
|
||||
cmd_done.eq(cnt==cmd_len)
|
||||
cmd_done.eq((cnt==cmd_len) & link.sink.ack)
|
||||
).Elif(data_send,
|
||||
link.sink.stb.eq(sink.stb),
|
||||
link.sink.sop.eq(0),
|
||||
|
@ -152,6 +151,7 @@ class SATATransportRX(Module):
|
|||
self.submodules += fsm
|
||||
|
||||
fsm.act("IDLE",
|
||||
clr_cnt.eq(1),
|
||||
If(link.source.stb & link.source.sop,
|
||||
If(test_type("REG_D2H"),
|
||||
NextState("RECEIVE_REG_D2H_CMD")
|
||||
|
@ -168,7 +168,7 @@ class SATATransportRX(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("RECEIVE_REG_D2H_CMD",
|
||||
cmd_len.eq(fis_reg_d2h_cmd_len),
|
||||
cmd_len.eq(fis_reg_d2h_cmd_len-1),
|
||||
cmd_receive.eq(1),
|
||||
If(cmd_done,
|
||||
NextState("PRESENT_REG_D2H_CMD")
|
||||
|
@ -182,7 +182,7 @@ class SATATransportRX(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("RECEIVE_DMA_ACTIVATE_D2H_CMD",
|
||||
cmd_len.eq(fis_dma_activate_d2h_cmd_len),
|
||||
cmd_len.eq(fis_dma_activate_d2h_cmd_len-1),
|
||||
cmd_receive.eq(1),
|
||||
If(cmd_done,
|
||||
NextState("PRESENT_DMA_ACTIVATE_D2H_CMD")
|
||||
|
@ -196,7 +196,7 @@ class SATATransportRX(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("RECEIVE_DATA_CMD",
|
||||
cmd_len.eq(fis_data_cmd_len),
|
||||
cmd_len.eq(fis_data_cmd_len-1),
|
||||
cmd_receive.eq(1),
|
||||
If(cmd_done,
|
||||
NextState("PRESENT_DATA")
|
||||
|
@ -236,7 +236,7 @@ class SATATransportRX(Module):
|
|||
).Elif(inc_cnt,
|
||||
cnt.eq(cnt+1)
|
||||
)
|
||||
self.comb += cmd_done.eq(cnt==cmd_len)
|
||||
self.comb += cmd_done.eq((cnt==cmd_len) & link.source.ack)
|
||||
self.comb += link.source.ack.eq(cmd_receive | (data_receive & source.ack))
|
||||
|
||||
class SATATransport(Module):
|
||||
|
|
Loading…
Reference in a new issue