From 67aaf09b532d873d766985138d3314d2c19e5ba6 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 11 Nov 2014 12:26:32 +0100 Subject: [PATCH] link: SATALinkLayer skeleton --- lib/sata/link/__init__.py | 154 ++++++++++++++++++++++++++------------ 1 file changed, 105 insertions(+), 49 deletions(-) diff --git a/lib/sata/link/__init__.py b/lib/sata/link/__init__.py index c864be83..972c99a8 100644 --- a/lib/sata/link/__init__.py +++ b/lib/sata/link/__init__.py @@ -4,80 +4,136 @@ from lib.sata.std import * from lib.sata.link import crc from lib.sata.link import scrambler -class SATALinkLayerTX(Module): - def __init__(self, dw): +# Todo: +# - 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.source = Source(phy_layout(dw)) + self.source = Source(link_layout(dw)) - ### + fsm = FSM(reset_state="IDLE") + self.submodules += fsm - # insert CRC + # TX + # insert CRC crc_inserter = crc.SATACRCInserter(link_layout(dw)) self.submodules += crc_inserter - # scramble + # 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)) + # graph + self.comb += [ + Record.connect(self.sink, crc_inserter.sink), + 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)) self.submodules += descrambler - # check CRC + # 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) + # graph + self.comb += [ + If(fsm.ongoing("H2D_COPY" & (rx_det == 0), + 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") - self.submodules += fsm + # 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") + tx_insert.eq(primitives["SYNC"]), + If(rx_primitive == "X_RDY", + NextState("D2H_RDY") + ).Elif(scrambler.stb & scrambler.sop, + NextState("H2D_RDY") + ) ) - fsm.act("SOF", - phy.sink.stb.eq(1), - phy.sink.d.eq(SOF_VAL), - NextState("COPY") + + # Host to Device + fsm.act("H2D_RDY", + tx_insert.eq(primitives["X_RDY"]), + If(rx_primitive == primitives["R_RDY"]), + NextState("H2D_SOF") ) - fsm.act("COPY", - phy.sink.stb.eq(1), - phy.sink.d.eq(), - NextState("EOF") + fsm.act("H2D_SOF", + tx_insert.eq(primitives["SOF"]), + If(phy.sink.ack, + NextState("H2D_COPY") + ) ) - fsm.act("EOF", - phy.sink.stb.eq(1), - phy.sink.d.eq(EOF_VAL), - NextState("") + fsm.act("H2D_COPY", + If(scrambler.stb & scrambler.ack & scramvbler.eop, + NextState("H2D_EOF") + ) ) - fsm.act("EOF", - phy.sink.stb.eq(1), - phy.sink.d.eq(EOF_VAL), - NextState("") + fsm.act("H2D_EOF", + tx_insert.eq(primitives["EOF"]), + If(phy.sink.ack, + NextState("H2D_WTRM") + ) ) - fsm.act("WTRM", - phy.sink.stb.eq(1), - phy.sink.d.eq(WTRM_VAL), - If(phy.source.stb & (phy.source.d == R_OK_VAL), + fsm.act("H2D_WTRM", + tx_insert.eq(primitives["WTRM"]), + If(rx_det == primitives["R_OK"]), + NextState("IDLE") + ).Elif(rx_det == primitives["R_ERR"], NextState("IDLE") - ).Elif(phy.source.stb & (phy.source.d == R_ERR_VAL), + ) + ) + + # 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") ) ) -- 2.30.2