link: add SATALinkLayer skeleton (wip)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 4 Nov 2014 16:35:46 +0000 (17:35 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 4 Nov 2014 21:55:31 +0000 (22:55 +0100)
lib/sata/link/__init__.py [new file with mode: 0644]
lib/sata/link/crc.py
lib/sata/link/scrambler.py
lib/sata/std.py

diff --git a/lib/sata/link/__init__.py b/lib/sata/link/__init__.py
new file mode 100644 (file)
index 0000000..c864be8
--- /dev/null
@@ -0,0 +1,83 @@
+from migen.fhdl.std import *
+
+from lib.sata.std import *
+from lib.sata.link import crc
+from lib.sata.link import scrambler
+
+class SATALinkLayerTX(Module):
+       def __init__(self, dw):
+               self.sink = Sink(link_layout(dw))
+               self.source = Source(phy_layout(dw))
+
+               ###
+
+       # insert CRC
+               crc_inserter = crc.SATACRCInserter(link_layout(dw))
+               self.submodules += crc_inserter
+
+       # scramble
+               scrambler = scrambler.SATAScrambler(link_layout(dw))
+               self.submodules += scrambler
+
+class SATALinkLayerRX(Module):
+       def __init__(self, dw):
+               self.sink = Sink(link_layout(dw))
+               self.source = Source(phy_layout(dw))
+
+               ###
+
+       # descramble
+               descrambler = descrambler.SATAScrambler(link_layout(dw))
+               self.submodules += descrambler
+
+       # check CRC
+               crc_checker = crc.SATACRCChecker(link_layout(dw))
+               self.submodules += crc_checker
+
+class SATALinkLayer(Module):
+       def __init__(self, phy, dw=32):
+               self.submodules.tx = SATALinkLayerTX(dw)
+               self.submodules.rx = SATALinkLayerRX(dw)
+
+               fsm = FSM(reset_state="IDLE")
+               self.submodules += fsm
+               fsm.act("IDLE",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(SYNC_VAL),
+                       NextState("RDY")
+               )
+               fsm.act("RDY",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(X_RDY_VAL)
+                       If(phy.source.stb & (phy.source.d == X_RDY_VAL),
+                               NextState("SOF")
+               )
+               fsm.act("SOF",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(SOF_VAL),
+                       NextState("COPY")
+               )
+               fsm.act("COPY",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(),
+                       NextState("EOF")
+               )
+               fsm.act("EOF",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(EOF_VAL),
+                       NextState("")
+               )
+               fsm.act("EOF",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(EOF_VAL),
+                       NextState("")
+               )
+               fsm.act("WTRM",
+                       phy.sink.stb.eq(1),
+                       phy.sink.d.eq(WTRM_VAL),
+                       If(phy.source.stb & (phy.source.d == R_OK_VAL),
+                               NextState("IDLE")
+                       ).Elif(phy.source.stb & (phy.source.d == R_ERR_VAL),
+                               NextState("IDLE")
+                       )
+               )
index 59c650a1780add734c12d1025d9d7b0769b86392..e7bb3bb0e6bb1efb1ea9c13bdb143cc19f54c8ca 100644 (file)
@@ -1,5 +1,8 @@
 from migen.fhdl.std import *
 from migen.genlib.misc import optree
+from migen.actorlib.crc import CRCInserter, CRCChecker
+
+from lib.sata.std import *
 
 class CRCEngine(Module):
        """Cyclic Redundancy Check Engine
@@ -54,7 +57,7 @@ class CRCEngine(Module):
                # compute and optimize CRC's LFSR
                curval = [[("new", i)] for i in range(width)]
                for i in range(width):
-                       feedback = curval.pop()         
+                       feedback = curval.pop()
                        for j in range(width-1):
                                if (polynom & (1<<(j+1))):
                                        curval[j] += feedback
@@ -104,3 +107,11 @@ class SATACRC(Module):
                        self.value.eq(reg_i),
                        self.error.eq(self.engine.next != self.check)
                ]
+
+class SATACRCInserter(CRCInserter):
+       def __init__(self, layout):
+               CRCInserter.__init__(self, SATACRC, layout)
+
+class SATACRCChecker(CRCChecker):
+       def __init__(self, layout):
+               CRCChecker.__init__(self, SATACRC, layout)
\ No newline at end of file
index e2aaa54bdb195e3deff86c92bf7b96d2f40f9219..8f301a1929aaef55cf7d220a1305dd20d3ad0800 100644 (file)
@@ -3,7 +3,7 @@ from migen.genlib.misc import optree
 
 @DecorateModule(InsertReset)
 @DecorateModule(InsertCE)
-class SATAScrambler(Module):
+class Scrambler(Module):
        """SATA Scrambler
 
        Implement a SATA Scrambler
@@ -65,3 +65,28 @@ class SATAScrambler(Module):
                        self.comb += next_value[n].eq(optree("^", eq))
 
                self.comb += self.value.eq(next_value)
+
+class SATAScrambler(Module):
+       def __init__(self, layout):
+               self.sink = sink = Sink(layout)
+               self.source = source = Source(layout)
+
+               ###
+
+               self.submodules.scrambler = Scrambler()
+               ongoing = Signal()
+               self.sync += [
+                       If(sink.stb & sink.ack,
+                               If(sink.eop,
+                                       ongoing.eq(0)
+                               ).Elsif(sink.sop,
+                                       ongoing.eq(1)
+                               )
+                       )
+               ]
+               self.comb += [
+                       self.scrambler.ce.eq(sink.stb & (sink.sop | ongoing)),
+                       self.scrambler.reset.eq(~ongoing),
+                       Record.connect(sink, source),
+                       source.d.eq(sink.d ^ self.scrambler.value)
+               ]
index 3f3ea2f45730430e890f5dafc7f0edc7a75ed330..b2370c5079095eb3b7e4914d0ba957b3f8af81a7 100644 (file)
@@ -1,8 +1,29 @@
 from migen.fhdl.std import *
 
+ALIGN_VAL   = 0x7B4A4ABC
+SYNC_VAL    = 0xB5B5957C
+R_RDY_VAL   = 0x4A4A957C
+R_OK_VAL    = 0x3535B57C
+R_ERR_VAL   = 0x5656B57C
+R_IP_VAL    = 0X5555B57C
+X_RDY_VAL   = 0x5757B57C
+CONT_VAL    = 0x9999AA7C
+WTRM_VAL    = 0x5858B57C
+SOF_VAL     = 0x3737B57C
+EOF_VAL     = 0xD5D5B57C
+HOLD_VAL    = 0xD5D5AA7C
+HOLD_ACK    = 0X9595AA7C
+
 def phy_layout(dw):
        layout = [
                ("p_packetized", True),
                ("d", dw)
        ]
        return layout
+
+def link_layout(dw):
+       layout = [
+               ("p_packetized", True),
+               ("d", dw)
+       ]
+       return layout