mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
transport: code SATATransportLayerRX (untested)
This commit is contained in:
parent
1aab9a449e
commit
ed9d9e1375
2 changed files with 155 additions and 2 deletions
|
@ -67,7 +67,7 @@ def transport_cmd_tx_layout():
|
||||||
("dma_buffer_offset", 32),
|
("dma_buffer_offset", 32),
|
||||||
("dma_transfer_count", 32),
|
("dma_transfer_count", 32),
|
||||||
]
|
]
|
||||||
return EndpointDescription(layout, packetized=True)
|
return EndpointDescription(layout, packetized=False)
|
||||||
|
|
||||||
def transport_cmd_rx_layout():
|
def transport_cmd_rx_layout():
|
||||||
layout = [
|
layout = [
|
||||||
|
@ -87,7 +87,7 @@ def transport_cmd_rx_layout():
|
||||||
("dma_buffer_offset", 32),
|
("dma_buffer_offset", 32),
|
||||||
("dma_transfer_count", 32)
|
("dma_transfer_count", 32)
|
||||||
]
|
]
|
||||||
return EndpointDescription(layout, packetized=True)
|
return EndpointDescription(layout, packetized=False)
|
||||||
|
|
||||||
def transport_data_layout(dw):
|
def transport_data_layout(dw):
|
||||||
layout = [
|
layout = [
|
||||||
|
|
|
@ -114,11 +114,164 @@ class SATATransportLayerTX(Module):
|
||||||
cnt.eq(cnt+1)
|
cnt.eq(cnt+1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _decode_cmd(signal, layout, obj):
|
||||||
|
r = []
|
||||||
|
for k, v in sorted(layout.items()):
|
||||||
|
start = v.word*32+v.offset
|
||||||
|
end = start+v.width
|
||||||
|
r.append(getattr(obj, k).eq(signal[start:end]))
|
||||||
|
return r
|
||||||
|
|
||||||
class SATATransportLayerRX(Module):
|
class SATATransportLayerRX(Module):
|
||||||
def __init__(self, link):
|
def __init__(self, link):
|
||||||
self.cmd = Source(transport_cmd_rx_layout())
|
self.cmd = Source(transport_cmd_rx_layout())
|
||||||
self.data = Source(transport_data_layout(32))
|
self.data = Source(transport_data_layout(32))
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
cmd_ndwords = max(fis_reg_d2h_cmd_len, fis_dma_activate_d2h_cmd_len, fis_dma_setup_cmd_len,
|
||||||
|
fis_data_cmd_len, fis_pio_setup_d2h_len)
|
||||||
|
encoded_cmd = Signal(cmd_ndwords*32)
|
||||||
|
|
||||||
|
cnt = Signal(max=cmd_ndwords+1)
|
||||||
|
clr_cnt = Signal()
|
||||||
|
inc_cnt = Signal()
|
||||||
|
|
||||||
|
cmd_len = Signal(flen(cnt))
|
||||||
|
|
||||||
|
cmd_receive = Signal()
|
||||||
|
data_receive = Signal()
|
||||||
|
cmd_done = Signal()
|
||||||
|
data_done = Signal()
|
||||||
|
|
||||||
|
fsm = FSM(reset_state="IDLE")
|
||||||
|
self.submodules += fsm
|
||||||
|
|
||||||
|
def test_type(name):
|
||||||
|
return link.source.d[:8] == fis_types[name]
|
||||||
|
|
||||||
|
fsm.act("IDLE",
|
||||||
|
If(link.source.stb & link.source.sop,
|
||||||
|
If(test_type("REG_D2H"]),
|
||||||
|
NextState("RECEIVE_REG_D2H_CMD")
|
||||||
|
).Elif(test_type("DMA_ACTIVATE_D2H"),
|
||||||
|
NextState("RECEIVE_DMA_ACTIVATE_D2H_CMD")
|
||||||
|
).Elif(test_type("DMA_SETUP"),
|
||||||
|
NextState("RECEIVE_DMA_SETUP_CMD"),
|
||||||
|
).Elif(test_type("DATA"),
|
||||||
|
NextState("RECEIVE_DATA_CMD"),
|
||||||
|
).Elif(test_type("PIO_SETUP_D2H"),
|
||||||
|
NextState("RECEIVE_PIO_SETUP_D2H_CMD"),
|
||||||
|
).Else(
|
||||||
|
# XXX: Better to ack?
|
||||||
|
link.source.ack.eq(1)
|
||||||
|
)
|
||||||
|
).Else(
|
||||||
|
link.source.ack.eq(1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_REG_D2H_CMD",
|
||||||
|
cmd_len.eq(fis_reg_d2h_cmd_len),
|
||||||
|
cmd_receive.eq(1),
|
||||||
|
If(cmd_done,
|
||||||
|
NextState("PRESENT_REG_D2H_CMD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("PRESENT_REG_D2H_CMD",
|
||||||
|
cmd.stb.eq(1),
|
||||||
|
_decode_cmd(encoded_cmd, fis_reg_d2h_layout ,cmd),
|
||||||
|
If(cmd.ack,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_DMA_ACTIVATE_D2H_CMD",
|
||||||
|
cmd_len.eq(fis_dma_activate_d2h_cmd_len),
|
||||||
|
cmd_receive.eq(1),
|
||||||
|
If(cmd_done,
|
||||||
|
NextState("PRESENT_DMA_ACTIVATE_D2H_CMD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("PRESENT_DMA_ACTIVATE_D2H_CMD",
|
||||||
|
cmd.stb.eq(1),
|
||||||
|
_decode_cmd(encoded_cmd, fis_dma_activate_d2h_layout ,cmd),
|
||||||
|
If(cmd.ack,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_DMA_SETUP_CMD",
|
||||||
|
cmd_len.eq(fis_dma_setup_cmd_len),
|
||||||
|
cmd_receive.eq(1),
|
||||||
|
If(cmd_done,
|
||||||
|
NextState("PRESENT_DMA_SETUP_CMD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("PRESENT_DMA_SETUP_CMD",
|
||||||
|
cmd.stb.eq(1),
|
||||||
|
_decode_cmd(encoded_cmd, fis_pio_setup_d2h_layout ,cmd),
|
||||||
|
If(cmd.ack,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_DATA_CMD",
|
||||||
|
cmd_len.eq(fis_data_cmd_len),
|
||||||
|
cmd_receive.eq(1),
|
||||||
|
If(cmd_done,
|
||||||
|
NextState("RECEIVE_DATA")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_DATA",
|
||||||
|
data_receive.eq(1),
|
||||||
|
If(data_done,
|
||||||
|
NextState("PRESENT_DATA_CMD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("DECODE_DATA",
|
||||||
|
cmd.stb.eq(1),
|
||||||
|
_decode_cmd(encoded_cmd, fis_data_layout ,cmd),
|
||||||
|
If(cmd.ack,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RECEIVE_PIO_SETUP_D2H_CMD",
|
||||||
|
cmd_len.eq(fis_pio_setup_d2h_len),
|
||||||
|
cmd_receive.eq(1),
|
||||||
|
If(cmd_done,
|
||||||
|
NextState("PRESENT_PIO_SETUP_D2H_CMD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("PRESENT_PIO_SETUP_D2H_CMD",
|
||||||
|
cmd.stb.eq(1),
|
||||||
|
_decode_cmd(encoded_cmd, fis_pio_setup_d2h_layout ,cmd),
|
||||||
|
If(cmd.ack,
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_cases = {}
|
||||||
|
for i in range(cmd_ndwords):
|
||||||
|
cmd_cases[i] = [encoded_cmd[32*i:32*(i+1)]).eq(link.source.d)]
|
||||||
|
|
||||||
|
self.sync += \
|
||||||
|
If(cmd_receive,
|
||||||
|
If(link.source.stb,
|
||||||
|
Case(cnt, cmd_cases),
|
||||||
|
inc_cnt.eq(1),
|
||||||
|
).Else(
|
||||||
|
inc_cnt.eq(0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.comb += cmd_done.eq(cnt==cmd_len)
|
||||||
|
|
||||||
|
self.comb += \
|
||||||
|
If(data_receive,
|
||||||
|
data.stb.eq(link.source.stb),
|
||||||
|
data.sop.eq(0), # XXX
|
||||||
|
data.eop.eq(link.source.eop),
|
||||||
|
data.d.eq(link.source.d),
|
||||||
|
data_done.eq(link.source.stb & link.source.eop)
|
||||||
|
)
|
||||||
|
self.comb += link.source.ack.eq(cmd_receive | (data_receive & data.ack))
|
||||||
|
|
||||||
class SATATransportLayer(Module):
|
class SATATransportLayer(Module):
|
||||||
def __init__(self, link):
|
def __init__(self, link):
|
||||||
self.submodules.tx = SATATransportLayerTX(link)
|
self.submodules.tx = SATATransportLayerTX(link)
|
||||||
|
|
Loading…
Reference in a new issue