link: SATALinkLayer skeleton

This commit is contained in:
Florent Kermarrec 2014-11-11 12:26:32 +01:00
parent 294855e292
commit 67aaf09b53
1 changed files with 117 additions and 61 deletions

View File

@ -4,13 +4,19 @@ from lib.sata.std import *
from lib.sata.link import crc from lib.sata.link import crc
from lib.sata.link import scrambler from lib.sata.link import scrambler
class SATALinkLayerTX(Module): # Todo:
def __init__(self, dw): # - TX: (optional) insert COND and scramble between COND and primitives
# - RX: manage COND, HOLD from device
class SATALinkLayer(Module):
def __init__(self, phy, dw=32):
self.sink = Sink(link_layout(dw)) self.sink = Sink(link_layout(dw))
self.source = Source(phy_layout(dw)) self.source = Source(link_layout(dw))
### fsm = FSM(reset_state="IDLE")
self.submodules += fsm
# TX
# insert CRC # insert CRC
crc_inserter = crc.SATACRCInserter(link_layout(dw)) crc_inserter = crc.SATACRCInserter(link_layout(dw))
self.submodules += crc_inserter self.submodules += crc_inserter
@ -19,14 +25,36 @@ class SATALinkLayerTX(Module):
scrambler = scrambler.SATAScrambler(link_layout(dw)) scrambler = scrambler.SATAScrambler(link_layout(dw))
self.submodules += scrambler self.submodules += scrambler
class SATALinkLayerRX(Module): # graph
def __init__(self, dw): self.comb += [
self.sink = Sink(link_layout(dw)) Record.connect(self.sink, crc_inserter.sink),
self.source = Source(phy_layout(dw)) Record.connect(crc_inserter, scrambler)
]
### # datas / primitives mux
tx_insert = Signal(32)
self.comb += [
If(tx_insert != 0,
phy.sink.stb.eq(1),
phy.sink.data.eq(tx_insert),
phy.sink.charisk.eq(0x0001),
).Elsif(fsm.ongoing("H2D_COPY"),
phy.sink.stb.eq(scrambler.source.stb),
phy.sink.data.eq(scrambler.source.data),
scrambler.source.ack.eq(phy.source.ack),
phy.sink.charisk.eq(0)
)
]
# descramble # RX
# datas / primitives detection
rx_det = Signal(32)
self.comb += \
If(phy.source.stb & (phy.source.charisk == 0b0001),
rx_det.eq(phy.source.data)
)
# descrambler
descrambler = descrambler.SATAScrambler(link_layout(dw)) descrambler = descrambler.SATAScrambler(link_layout(dw))
self.submodules += descrambler self.submodules += descrambler
@ -34,50 +62,78 @@ class SATALinkLayerRX(Module):
crc_checker = crc.SATACRCChecker(link_layout(dw)) crc_checker = crc.SATACRCChecker(link_layout(dw))
self.submodules += crc_checker self.submodules += crc_checker
class SATALinkLayer(Module): # graph
def __init__(self, phy, dw=32): self.comb += [
self.submodules.tx = SATALinkLayerTX(dw) If(fsm.ongoing("H2D_COPY" & (rx_det == 0),
self.submodules.rx = SATALinkLayerRX(dw) descrambler.sink.stb.eq(phy.source.stb & (phy.charisk == 0)),
descrambler.sink.d.eq(phy.source.d),
)
Record.connect(descrambler.source, crc_checker.sink),
Record.connect(crc_checker.source, self.source)
]
fsm = FSM(reset_state="IDLE") # FSM
self.submodules += fsm
fsm.act("IDLE", fsm.act("IDLE",
phy.sink.stb.eq(1), tx_insert.eq(primitives["SYNC"]),
phy.sink.d.eq(SYNC_VAL), If(rx_primitive == "X_RDY",
NextState("RDY") NextState("D2H_RDY")
).Elif(scrambler.stb & scrambler.sop,
NextState("H2D_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), # Host to Device
phy.sink.d.eq(SOF_VAL), fsm.act("H2D_RDY",
NextState("COPY") tx_insert.eq(primitives["X_RDY"]),
If(rx_primitive == primitives["R_RDY"]),
NextState("H2D_SOF")
) )
fsm.act("COPY", fsm.act("H2D_SOF",
phy.sink.stb.eq(1), tx_insert.eq(primitives["SOF"]),
phy.sink.d.eq(), If(phy.sink.ack,
NextState("EOF") NextState("H2D_COPY")
) )
fsm.act("EOF",
phy.sink.stb.eq(1),
phy.sink.d.eq(EOF_VAL),
NextState("")
) )
fsm.act("EOF", fsm.act("H2D_COPY",
phy.sink.stb.eq(1), If(scrambler.stb & scrambler.ack & scramvbler.eop,
phy.sink.d.eq(EOF_VAL), NextState("H2D_EOF")
NextState("")
) )
fsm.act("WTRM", )
phy.sink.stb.eq(1), fsm.act("H2D_EOF",
phy.sink.d.eq(WTRM_VAL), tx_insert.eq(primitives["EOF"]),
If(phy.source.stb & (phy.source.d == R_OK_VAL), If(phy.sink.ack,
NextState("H2D_WTRM")
)
)
fsm.act("H2D_WTRM",
tx_insert.eq(primitives["WTRM"]),
If(rx_det == primitives["R_OK"]),
NextState("IDLE") NextState("IDLE")
).Elif(phy.source.stb & (phy.source.d == R_ERR_VAL), ).Elif(rx_det == primitives["R_ERR"],
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["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") NextState("IDLE")
) )
) )