From: Florent Kermarrec Date: Wed, 3 Dec 2014 10:50:31 +0000 (+0100) Subject: link: manage CONT on RX path X-Git-Tag: 24jan2021_ls180~2572^2~155 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d3974882e4ab791ebc00502fbbd681181761f17a;p=litex.git link: manage CONT on RX path --- diff --git a/lib/sata/link/__init__.py b/lib/sata/link/__init__.py index 07df3adc..0570916f 100644 --- a/lib/sata/link/__init__.py +++ b/lib/sata/link/__init__.py @@ -4,10 +4,11 @@ from migen.genlib.fsm import FSM, NextState from lib.sata.std import * from lib.sata.link.crc import SATACRCInserter, SATACRCChecker from lib.sata.link.scrambler import SATAScrambler -from lib.sata.link.cont import SATACONTInserter +from lib.sata.link.cont import SATACONTInserter, SATACONTRemover -# Todo: -# - RX: manage CONT +# TODO: +# - Test D2H +# - Do more tests class SATALinkLayer(Module): def __init__(self, phy): @@ -19,67 +20,75 @@ class SATALinkLayer(Module): # TX # insert CRC - crc = SATACRCInserter(link_layout(32)) - self.submodules += crc + tx_crc = SATACRCInserter(link_layout(32)) + self.submodules += tx_crc # scramble - scrambler = SATAScrambler(link_layout(32)) - self.submodules += scrambler + tx_scrambler = SATAScrambler(link_layout(32)) + self.submodules += tx_scrambler # graph self.comb += [ - Record.connect(self.sink, crc.sink), - Record.connect(crc.source, scrambler.sink) + Record.connect(self.sink, tx_crc.sink), + Record.connect(tx_crc.source, tx_scrambler.sink) ] # inserter CONT and scrambled data between # CONT and next primitive - cont = SATACONTInserter(phy_layout(32)) - self.submodules += cont + tx_cont = SATACONTInserter(phy_layout(32)) + self.submodules += tx_cont # datas / primitives mux tx_insert = Signal(32) self.comb += [ If(tx_insert != 0, - cont.sink.stb.eq(1), - cont.sink.data.eq(tx_insert), - cont.sink.charisk.eq(0x0001), + tx_cont.sink.stb.eq(1), + tx_cont.sink.data.eq(tx_insert), + tx_cont.sink.charisk.eq(0x0001), ).Elif(fsm.ongoing("H2D_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) + 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) ) ] # graph - self.comb += Record.connect(cont.source, phy.sink) + self.comb += Record.connect(tx_cont.source, phy.sink) # RX + + # CONT remover + rx_cont = SATACONTRemover(phy_layout(32)) + self.submodules += rx_cont + + # graph + self.comb += Record.connect(phy.source, rx_cont.sink) + # datas / primitives detection rx_det = Signal(32) self.comb += \ - If(phy.source.stb & (phy.source.charisk == 0b0001), - rx_det.eq(phy.source.data) + If(rx_cont.source.stb & (rx_cont.source.charisk == 0b0001), + rx_det.eq(rx_cont.source.data) ) # descrambler - descrambler = SATAScrambler(link_layout(32)) - self.submodules += descrambler + rx_scrambler = SATAScrambler(link_layout(32)) + self.submodules += rx_scrambler # check CRC - crc_checker = SATACRCChecker(link_layout(32)) - self.submodules += crc_checker + rx_crc = SATACRCChecker(link_layout(32)) + self.submodules += rx_crc # graph self.comb += [ If(fsm.ongoing("D2H_COPY") & (rx_det == 0), - descrambler.sink.stb.eq(phy.source.stb & (phy.source.charisk == 0)), - descrambler.sink.d.eq(phy.source.data), + rx_scrambler.sink.stb.eq(rx_cont.source.stb & (rx_cont.source.charisk == 0)), + rx_scrambler.sink.d.eq(rx_cont.source.data), ), - phy.source.ack.eq(1), - Record.connect(descrambler.source, crc_checker.sink), - Record.connect(crc_checker.source, self.source) + rx_cont.source.ack.eq(1), + Record.connect(rx_scrambler.source, rx_crc.sink), + Record.connect(rx_crc.source, self.source) ] # FSM @@ -87,7 +96,7 @@ class SATALinkLayer(Module): tx_insert.eq(primitives["SYNC"]), If(rx_det == primitives["X_RDY"], NextState("D2H_RDY") - ).Elif(scrambler.source.stb & scrambler.source.sop, + ).Elif(tx_scrambler.source.stb & tx_scrambler.source.sop, NextState("H2D_RDY") ) ) @@ -108,9 +117,9 @@ class SATALinkLayer(Module): fsm.act("H2D_COPY", If(rx_det == primitives["HOLD"], tx_insert.eq(primitives["HOLDA"]), - ).Elif(~scrambler.source.stb, + ).Elif(~tx_scrambler.source.stb, tx_insert.eq(primitives["HOLD"]), - ).Elif(scrambler.source.stb & scrambler.source.eop & scrambler.source.ack, + ).Elif(tx_scrambler.source.stb & tx_scrambler.source.eop & tx_scrambler.source.ack, NextState("H2D_EOF") ) ) diff --git a/lib/sata/link/cont.py b/lib/sata/link/cont.py index 8ec89fff..6847f6db 100644 --- a/lib/sata/link/cont.py +++ b/lib/sata/link/cont.py @@ -12,6 +12,7 @@ class SATACONTInserter(Module): ### # Detect consecutive primitives + # tn insert CONT cnt = Signal(2) is_primitive = Signal() last_was_primitive = Signal() @@ -46,7 +47,7 @@ class SATACONTInserter(Module): ) ) - # Repeated primitives scranbler + # scranbler (between CONT and next primitive) scrambler = Scrambler() self.submodules += scrambler self.comb += [ @@ -72,3 +73,43 @@ class SATACONTInserter(Module): ) ) ] + +class SATACONTRemover(Module): + def __init__(self, layout): + self.sink = sink = Sink(layout) + self.source = source = Source(layout) + + ### + + # Detect CONT + is_primitive = Signal() + is_cont = Signal() + in_cont = Signal() + cont_ongoing = Signal() + + self.comb += [ + is_primitive.eq(sink.charisk != 0), + is_cont.eq(is_primitive & sink.data == primitives["CONT"]) + ] + self.sync += \ + If(is_cont, + in_cont.eq(1) + ).Elif(is_primitive, + in_cont.eq(0) + ) + self.comb += cont_ongoing.eq(is_cont | (in_cont & ~is_primitive)) + + # Datapath + last_primitive = Signal() + self.sync += [ + If(is_primitive & ~is_cont, + last_primitive.eq(sink.data) + ) + ] + self.comb += [ + Record.connect(sink, source), + If(cont_ongoing, + self.source.charisk.eq(0b0001), + self.source.data.eq(last_primitive) + ) + ] diff --git a/lib/sata/link/test/bfm.py b/lib/sata/link/test/bfm.py index 792f8f9e..66a46eb9 100644 --- a/lib/sata/link/test/bfm.py +++ b/lib/sata/link/test/bfm.py @@ -132,6 +132,7 @@ class BFM(Module): print("----") def dword_callback(self, dword): + # CONT detection if dword == primitives["CONT"]: self.rx_cont_ongoing = True elif is_primitive(dword): @@ -148,7 +149,7 @@ class BFM(Module): elif dword == primitives["HOLD"]: self.phy.send(primitives["HOLDA"]) - # packet capture + # Packet capture elif dword == primitives["EOF"]: self.rx_packet_ongoing = False self.packet_callback(self.rx_packet)