mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
link: add SATALinkLayer skeleton (wip)
This commit is contained in:
parent
8f6354f2a3
commit
353e7fc13b
4 changed files with 142 additions and 2 deletions
lib/sata
83
lib/sata/link/__init__.py
Normal file
83
lib/sata/link/__init__.py
Normal file
|
@ -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")
|
||||||
|
)
|
||||||
|
)
|
|
@ -1,5 +1,8 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib.misc import optree
|
from migen.genlib.misc import optree
|
||||||
|
from migen.actorlib.crc import CRCInserter, CRCChecker
|
||||||
|
|
||||||
|
from lib.sata.std import *
|
||||||
|
|
||||||
class CRCEngine(Module):
|
class CRCEngine(Module):
|
||||||
"""Cyclic Redundancy Check Engine
|
"""Cyclic Redundancy Check Engine
|
||||||
|
@ -104,3 +107,11 @@ class SATACRC(Module):
|
||||||
self.value.eq(reg_i),
|
self.value.eq(reg_i),
|
||||||
self.error.eq(self.engine.next != self.check)
|
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)
|
|
@ -3,7 +3,7 @@ from migen.genlib.misc import optree
|
||||||
|
|
||||||
@DecorateModule(InsertReset)
|
@DecorateModule(InsertReset)
|
||||||
@DecorateModule(InsertCE)
|
@DecorateModule(InsertCE)
|
||||||
class SATAScrambler(Module):
|
class Scrambler(Module):
|
||||||
"""SATA Scrambler
|
"""SATA Scrambler
|
||||||
|
|
||||||
Implement a SATA Scrambler
|
Implement a SATA Scrambler
|
||||||
|
@ -65,3 +65,28 @@ class SATAScrambler(Module):
|
||||||
self.comb += next_value[n].eq(optree("^", eq))
|
self.comb += next_value[n].eq(optree("^", eq))
|
||||||
|
|
||||||
self.comb += self.value.eq(next_value)
|
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)
|
||||||
|
]
|
||||||
|
|
|
@ -1,8 +1,29 @@
|
||||||
from migen.fhdl.std import *
|
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):
|
def phy_layout(dw):
|
||||||
layout = [
|
layout = [
|
||||||
("p_packetized", True),
|
("p_packetized", True),
|
||||||
("d", dw)
|
("d", dw)
|
||||||
]
|
]
|
||||||
return layout
|
return layout
|
||||||
|
|
||||||
|
def link_layout(dw):
|
||||||
|
layout = [
|
||||||
|
("p_packetized", True),
|
||||||
|
("d", dw)
|
||||||
|
]
|
||||||
|
return layout
|
||||||
|
|
Loading…
Reference in a new issue