From: Florent Kermarrec Date: Thu, 11 Dec 2014 20:56:56 +0000 (+0100) Subject: transport: code SATATransportLayerRX (untested) X-Git-Tag: 24jan2021_ls180~2572^2~142 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ed9d9e137580231356eec0fc4d72e6a847d37e1a;p=litex.git transport: code SATATransportLayerRX (untested) --- diff --git a/lib/sata/std.py b/lib/sata/std.py index bd054da3..19848926 100644 --- a/lib/sata/std.py +++ b/lib/sata/std.py @@ -67,7 +67,7 @@ def transport_cmd_tx_layout(): ("dma_buffer_offset", 32), ("dma_transfer_count", 32), ] - return EndpointDescription(layout, packetized=True) + return EndpointDescription(layout, packetized=False) def transport_cmd_rx_layout(): layout = [ @@ -87,7 +87,7 @@ def transport_cmd_rx_layout(): ("dma_buffer_offset", 32), ("dma_transfer_count", 32) ] - return EndpointDescription(layout, packetized=True) + return EndpointDescription(layout, packetized=False) def transport_data_layout(dw): layout = [ diff --git a/lib/sata/transport/__init__.py b/lib/sata/transport/__init__.py index ba0161dc..41785905 100644 --- a/lib/sata/transport/__init__.py +++ b/lib/sata/transport/__init__.py @@ -114,11 +114,164 @@ class SATATransportLayerTX(Module): 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): def __init__(self, link): self.cmd = Source(transport_cmd_rx_layout()) 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): def __init__(self, link): self.submodules.tx = SATATransportLayerTX(link)