bfm: dma_skeleton

This commit is contained in:
Florent Kermarrec 2014-12-13 01:18:08 +01:00
parent 66ef7950ab
commit eb226c1ade
4 changed files with 78 additions and 12 deletions

View File

@ -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),
)
]

View File

@ -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,

View File

@ -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)

View File

@ -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):