link: split SATALinkLayer in SATALinkLayerTX and SATALinkLayerRX
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 3 Dec 2014 14:29:01 +0000 (15:29 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 3 Dec 2014 14:29:01 +0000 (15:29 +0100)
lib/sata/link/.keep_me [deleted file]
lib/sata/link/__init__.py

diff --git a/lib/sata/link/.keep_me b/lib/sata/link/.keep_me
deleted file mode 100644 (file)
index e69de29..0000000
index 0570916fdc74ee4b788fdaf025e3b61e0ea28ec5..dff5972576c4ac8b74e97783a7c004f03af99af8 100644 (file)
@@ -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