From: Florent Kermarrec Date: Wed, 3 Dec 2014 14:29:01 +0000 (+0100) Subject: link: split SATALinkLayer in SATALinkLayerTX and SATALinkLayerRX X-Git-Tag: 24jan2021_ls180~2572^2~154 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ddd4b65f44d33fec8b3e4e77603bdbec70e43687;p=litex.git link: split SATALinkLayer in SATALinkLayerTX and SATALinkLayerRX --- diff --git a/lib/sata/link/.keep_me b/lib/sata/link/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/sata/link/__init__.py b/lib/sata/link/__init__.py index 0570916f..dff59725 100644 --- a/lib/sata/link/__init__.py +++ b/lib/sata/link/__init__.py @@ -7,159 +7,192 @@ from lib.sata.link.scrambler import SATAScrambler from lib.sata.link.cont import SATACONTInserter, SATACONTRemover # TODO: -# - Test D2H # - Do more tests -class SATALinkLayer(Module): +from_rx = [ + ("idle", 1), + ("insert", 32), + ("det", 32) +] + +class SATALinkLayerTX(Module): def __init__(self, phy): self.sink = Sink(link_layout(32)) - self.source = Source(link_layout(32)) + self.from_rx = Sink(from_rx) + + ### fsm = FSM(reset_state="IDLE") self.submodules += fsm - # TX # insert CRC - tx_crc = SATACRCInserter(link_layout(32)) - self.submodules += tx_crc + crc = SATACRCInserter(link_layout(32)) + self.submodules += crc # scramble - tx_scrambler = SATAScrambler(link_layout(32)) - self.submodules += tx_scrambler + scrambler = SATAScrambler(link_layout(32)) + self.submodules += scrambler - # graph + # connect CRC / scrambler self.comb += [ - Record.connect(self.sink, tx_crc.sink), - Record.connect(tx_crc.source, tx_scrambler.sink) + Record.connect(self.sink, crc.sink), + Record.connect(crc.source, scrambler.sink) ] # inserter CONT and scrambled data between # CONT and next primitive - tx_cont = SATACONTInserter(phy_layout(32)) - self.submodules += tx_cont + cont = SATACONTInserter(phy_layout(32)) + self.submodules += cont # datas / primitives mux - tx_insert = Signal(32) + insert = Signal(32) self.comb += [ - If(tx_insert != 0, - tx_cont.sink.stb.eq(1), - tx_cont.sink.data.eq(tx_insert), - tx_cont.sink.charisk.eq(0x0001), - ).Elif(fsm.ongoing("H2D_COPY"), - tx_cont.sink.stb.eq(tx_scrambler.source.stb), - tx_cont.sink.data.eq(tx_scrambler.source.d), - tx_scrambler.source.ack.eq(tx_cont.sink.ack), - tx_cont.sink.charisk.eq(0) + If(self.from_rx.insert, + cont.sink.stb.eq(1), + cont.sink.data.eq(self.from_rx.insert), + cont.sink.charisk.eq(0x0001), + ). + Elif(insert, + cont.sink.stb.eq(1), + cont.sink.data.eq(insert), + cont.sink.charisk.eq(0x0001), + ).Elif(fsm.ongoing("COPY"), + cont.sink.stb.eq(scrambler.source.stb), + cont.sink.data.eq(scrambler.source.d), + scrambler.source.ack.eq(cont.sink.ack), + cont.sink.charisk.eq(0) ) ] + self.comb += Record.connect(cont.source, phy.sink) - # graph - self.comb += Record.connect(tx_cont.source, phy.sink) + # FSM + fsm.act("IDLE", + insert.eq(primitives["SYNC"]), + If(scrambler.source.stb & scrambler.source.sop, + If(self.from_rx.idle, + NextState("RDY") + ) + ) + ) + fsm.act("RDY", + insert.eq(primitives["X_RDY"]), + If(self.from_rx.det == primitives["R_RDY"], + NextState("SOF") + ) + ) + fsm.act("SOF", + insert.eq(primitives["SOF"]), + If(phy.sink.ack, + NextState("COPY") + ) + ) + fsm.act("COPY", + If(self.from_rx.det == primitives["HOLD"], + insert.eq(primitives["HOLDA"]), + ).Elif(~scrambler.source.stb, + insert.eq(primitives["HOLD"]), + ).Elif(scrambler.source.stb & scrambler.source.eop & scrambler.source.ack, + NextState("EOF") + ) + ) + fsm.act("EOF", + insert.eq(primitives["EOF"]), + If(phy.sink.ack, + NextState("WTRM") + ) + ) + fsm.act("WTRM", + insert.eq(primitives["WTRM"]), + If(self.from_rx.det == primitives["R_OK"], + NextState("IDLE") + ).Elif(self.from_rx.det == primitives["R_ERR"], + NextState("IDLE") + ) + ) - # RX +class SATALinkLayerRX(Module): + def __init__(self, phy): + self.source = Source(link_layout(32)) + self.to_tx = Source(from_rx) - # CONT remover - rx_cont = SATACONTRemover(phy_layout(32)) - self.submodules += rx_cont + ### - # graph - self.comb += Record.connect(phy.source, rx_cont.sink) + fsm = FSM(reset_state="IDLE") + self.submodules += fsm + + # CONT remover + cont = SATACONTRemover(phy_layout(32)) + self.submodules += cont + self.comb += Record.connect(phy.source, cont.sink) # datas / primitives detection - rx_det = Signal(32) + insert = Signal(32) + det = Signal(32) self.comb += \ - If(rx_cont.source.stb & (rx_cont.source.charisk == 0b0001), - rx_det.eq(rx_cont.source.data) + If(cont.source.stb & (cont.source.charisk == 0b0001), + det.eq(cont.source.data) ) # descrambler - rx_scrambler = SATAScrambler(link_layout(32)) - self.submodules += rx_scrambler + scrambler = SATAScrambler(link_layout(32)) + self.submodules += scrambler # check CRC - rx_crc = SATACRCChecker(link_layout(32)) - self.submodules += rx_crc + crc = SATACRCChecker(link_layout(32)) + self.submodules += crc # graph self.comb += [ - If(fsm.ongoing("D2H_COPY") & (rx_det == 0), - rx_scrambler.sink.stb.eq(rx_cont.source.stb & (rx_cont.source.charisk == 0)), - rx_scrambler.sink.d.eq(rx_cont.source.data), + If(fsm.ongoing("COPY") & (det == 0), + scrambler.sink.stb.eq(cont.source.stb & (cont.source.charisk == 0)), + scrambler.sink.d.eq(cont.source.data), ), - rx_cont.source.ack.eq(1), - Record.connect(rx_scrambler.source, rx_crc.sink), - Record.connect(rx_crc.source, self.source) + cont.source.ack.eq(1), + Record.connect(scrambler.source, crc.sink), + Record.connect(crc.source, self.source) ] - # FSM + # FSM fsm.act("IDLE", - tx_insert.eq(primitives["SYNC"]), - If(rx_det == primitives["X_RDY"], - NextState("D2H_RDY") - ).Elif(tx_scrambler.source.stb & tx_scrambler.source.sop, - NextState("H2D_RDY") + If(det == primitives["X_RDY"], + NextState("RDY") ) ) - - # Host to Device - fsm.act("H2D_RDY", - tx_insert.eq(primitives["X_RDY"]), - If(rx_det == primitives["R_RDY"], - NextState("H2D_SOF") + fsm.act("RDY", + insert.eq(primitives["R_RDY"]), + If(det == primitives["SOF"], + NextState("COPY") ) ) - fsm.act("H2D_SOF", - tx_insert.eq(primitives["SOF"]), - If(phy.sink.ack, - NextState("H2D_COPY") + fsm.act("COPY", + If(det == primitives["HOLD"], + insert.eq(primitives["HOLDA"]) + ).Elif(det == primitives["EOF"], + NextState("WTRM") ) ) - fsm.act("H2D_COPY", - If(rx_det == primitives["HOLD"], - tx_insert.eq(primitives["HOLDA"]), - ).Elif(~tx_scrambler.source.stb, - tx_insert.eq(primitives["HOLD"]), - ).Elif(tx_scrambler.source.stb & tx_scrambler.source.eop & tx_scrambler.source.ack, - NextState("H2D_EOF") + fsm.act("EOF", + If(det == primitives["WTRM"], + NextState("WTRM") ) ) - fsm.act("H2D_EOF", - tx_insert.eq(primitives["EOF"]), - If(phy.sink.ack, - NextState("H2D_WTRM") - ) - ) - fsm.act("H2D_WTRM", - tx_insert.eq(primitives["WTRM"]), - If(rx_det == primitives["R_OK"], - NextState("IDLE") - ).Elif(rx_det == primitives["R_ERR"], + fsm.act("WTRM", + insert.eq(primitives["R_OK"]), + If(det == primitives["SYNC"], NextState("IDLE") ) ) - # Device to Host - fsm.act("D2H_RDY", - tx_insert.eq(primitives["R_RDY"]), - If(rx_det == primitives["SOF"], - NextState("D2H_COPY") - ) - ) - fsm.act("D2H_COPY", - If(rx_det == primitives["HOLD"], - tx_insert.eq(primitives["HOLDA"]) - ).Elif(rx_det == primitives["EOF"], - NextState("D2H_WTRM") - ) - ) - fsm.act("D2H_EOF", - If(rx_det == primitives["WTRM"], - NextState("D2H_WTRM") - ) - ) - fsm.act("D2H_WTRM", - tx_insert.eq(primitives["R_OK"]), - If(rx_det == primitives["SYNC"], - NextState("IDLE") - ) - ) + # to TX + self.comb += [ + self.to_tx.idle.eq(fsm.ongoing("IDLE")), + self.to_tx.insert.eq(insert), + self.to_tx.det.eq(det) + ] + +class SATALinkLayer(Module): + def __init__(self, phy): + self.submodules.tx = SATALinkLayerTX(phy) + self.submodules.rx = SATALinkLayerRX(phy) + self.comb += Record.connect(self.rx.to_tx, self.tx.from_rx) + self.sink, self.source = self.tx.sink, self.rx.source