From: Florent Kermarrec Date: Sat, 27 Sep 2014 14:10:39 +0000 (+0200) Subject: add tx_reset_fsm and rx_reset_fsm X-Git-Tag: 24jan2021_ls180~2572^2~190 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=45f7f8aff55972b13f80957199857a8d96fdd074;p=litex.git add tx_reset_fsm and rx_reset_fsm --- diff --git a/lib/sata/k7sataphy/__init__.py b/lib/sata/k7sataphy/__init__.py index d985b0cc..8bcd029b 100644 --- a/lib/sata/k7sataphy/__init__.py +++ b/lib/sata/k7sataphy/__init__.py @@ -13,16 +13,28 @@ class K7SATAPHY(Module): self.sink = Sink([("d", 32)], True) self.source = Source([("d", 32)], True) + # GTX gtx = K7SATAPHYGTX(pads, "SATA3") self.comb += [ gtx.rxrate.eq(0b000), gtx.txrate.eq(0b000), ] - clocking = K7SATAPHYCRG(pads, gtx, clk_freq) + self.submodules += gtx + + # CRG / CTRL + crg = K7SATAPHYCRG(pads, gtx, clk_freq) + if host: + ctrl = K7SATAPHYHostCtrl(gtx) + else: + ctrl = K7SATAPHYDeviceCtrl(gtx) + self.submodules += crg, ctrl + self.comb += ctrl.start.eq(crg.ready) + + # DATAPATH rxalign = K7SATAPHYRXAlign() rxconvert = K7SATAPHYRXConvert() txconvert = K7SATAPHYTXConvert() - self.submodules += gtx, clocking, rxalign, rxconvert, txconvert + self.submodules += rxalign, rxconvert, txconvert self.comb += [ rxalign.rxdata_i.eq(gtx.rxdata), rxalign.rxcharisk_i.eq(gtx.rxcharisk), @@ -33,13 +45,8 @@ class K7SATAPHY(Module): gtx.txcharisk.eq(txconvert.txcharisk) ] - if host: - ctrl = K7SATAPHYHostCtrl(gtx) - else: - ctrl = K7SATAPHYDeviceCtrl(gtx) - self.submodules += ctrl self.comb += [ - If(ctrl.link_up, + If(ctrl.ready, txconvert.sink.stb.eq(self.sink.stb), txconvert.sink.data.eq(self.sink.d), txconvert.sink.charisk.eq(0), diff --git a/lib/sata/k7sataphy/crg.py b/lib/sata/k7sataphy/crg.py index df14b5f2..82ac4f7e 100644 --- a/lib/sata/k7sataphy/crg.py +++ b/lib/sata/k7sataphy/crg.py @@ -27,6 +27,7 @@ class K7SATAPHYReconfig(Module): class K7SATAPHYCRG(Module): def __init__(self, pads, gtx, clk_freq): self.reset = Signal() + self.ready = Signal() self.clock_domains.cd_sata_tx = ClockDomain() self.clock_domains.cd_sata_rx = ClockDomain() @@ -79,7 +80,6 @@ class K7SATAPHYCRG(Module): p_CLKOUT1_DIVIDE=8, p_CLKOUT1_PHASE=0.000, o_CLKOUT1=mmcm_clk1_o, ), Instance("BUFG", i_I=mmcm_clk0_o, o_O=self.cd_sata_tx.clk), - Instance("BUFG", i_I=mmcm_clk1_o, o_O=self.cd_sata.clk), ] self.comb += [ gtx.txusrclk.eq(self.cd_sata_tx.clk), @@ -98,7 +98,7 @@ class K7SATAPHYCRG(Module): gtx.rxusrclk2.eq(self.cd_sata_rx.clk) ] - # TX buffer bypass logic + # Bypass TX buffer self.comb += [ gtx.txphdlyreset.eq(0), gtx.txphalignen.eq(0), @@ -107,7 +107,7 @@ class K7SATAPHYCRG(Module): gtx.txphinit.eq(0) ] - # RX buffer bypass logic + # Bypass RX buffer self.comb += [ gtx.rxphdlyreset.eq(0), gtx.rxdlyen.eq(0), @@ -115,7 +115,6 @@ class K7SATAPHYCRG(Module): gtx.rxphalignen.eq(0), ] - # Configuration Reset # After configuration, GTX resets have to stay low for at least 500ns # See AR43482 @@ -126,57 +125,111 @@ class K7SATAPHYCRG(Module): self.sync += If(~reset_en, reset_en_cnt.eq(reset_en_cnt-1)) self.comb += reset_en.eq(reset_en_cnt == 0) - - # once channel TX is reseted, reset TX buffer - txbuffer_reseted = Signal() - self.sync += \ - If(gtx.txresetdone, - If(~txbuffer_reseted, - gtx.txdlysreset.eq(1), - txbuffer_reseted.eq(1) - ).Else( - gtx.txdlysreset.eq(0) - ) + # TX Reset FSM + tx_reset_fsm = FSM(reset_state="IDLE") + self.submodules += tx_reset_fsm + tx_reset_fsm.act("IDLE", + gtx.txuserrdy.eq(0), + gtx.gttxreset.eq(0), + gtx.txdlysreset.eq(0), + If(reset_en, + NextState("RESET_ALL"), ) - - # once channel RX is reseted, reset RX buffer - rxbuffer_reseted = Signal() - self.sync += \ - If(gtx.rxresetdone, - If(~rxbuffer_reseted, - gtx.rxdlysreset.eq(1), - rxbuffer_reseted.eq(1) - ).Else( - gtx.rxdlysreset.eq(0) - ) + ) + tx_reset_fsm.act("RESET_ALL", + gtx.txuserrdy.eq(0), + gtx.gttxreset.eq(1), + gtx.txdlysreset.eq(1), + If(gtx.cplllock & mmcm_locked, + NextState("RELEASE_GTXRESET") + ) + ) + tx_reset_fsm.act("RELEASE_GTXRESET", + gtx.txuserrdy.eq(1), + gtx.gttxreset.eq(0), + gtx.txdlysreset.eq(1), + If(self.reset, + NextState("RESET_ALL") + ).Elif(gtx.txresetdone, + NextState("RELEASE_DLYRESET") ) + ) + tx_reset_fsm.act("RELEASE_DLYRESET", + gtx.txuserrdy.eq(1), + gtx.gttxreset.eq(0), + gtx.txdlysreset.eq(0), + If(self.reset, + NextState("RESET_ALL") + ).Elif(gtx.txdlysresetdone, + NextState("READY") + ) + ) + tx_reset_fsm.act("READY", + gtx.txuserrdy.eq(1), + gtx.gttxreset.eq(0), + gtx.txdlysreset.eq(0), + If(self.reset, + NextState("RESET_ALL") + ) + ) - # Reset - # initial reset generation - rst_cnt = Signal(8) - rst_cnt_done = Signal() - self.sync += \ - If(~rst_cnt_done, - rst_cnt.eq(rst_cnt+1) + # RX Reset FSM + rx_reset_fsm = FSM(reset_state="IDLE") + self.submodules += rx_reset_fsm + rx_reset_fsm.act("IDLE", + gtx.rxuserrdy.eq(0), + gtx.gtrxreset.eq(0), + gtx.rxdlysreset.eq(0), + If(reset_en, + NextState("RESET_ALL"), + ) + ) + rx_reset_fsm.act("RESET_ALL", + gtx.rxuserrdy.eq(0), + gtx.gtrxreset.eq(1), + gtx.rxdlysreset.eq(1), + If(gtx.cplllock & mmcm_locked, + NextState("RELEASE_GTXRESET") + ) + ) + rx_reset_fsm.act("RELEASE_GTXRESET", + gtx.rxuserrdy.eq(1), + gtx.gtrxreset.eq(0), + gtx.rxdlysreset.eq(1), + If(self.reset, + NextState("RESET_ALL") + ).Elif(gtx.rxresetdone, + NextState("RELEASE_DLYRESET") + ) + ) + rx_reset_fsm.act("RELEASE_DLYRESET", + gtx.rxuserrdy.eq(1), + gtx.gtrxreset.eq(0), + gtx.rxdlysreset.eq(0), + If(self.reset, + NextState("RESET_ALL") + ).Elif(gtx.rxdlysresetdone, + NextState("READY") + ) + ) + rx_reset_fsm.act("READY", + gtx.rxuserrdy.eq(1), + gtx.gtrxreset.eq(0), + gtx.rxdlysreset.eq(0), + If(self.reset, + NextState("RESET_ALL") ) - self.comb += rst_cnt_done.eq(rst_cnt==255) + ) - self.comb += [ - # GTXE2 - gtx.rxuserrdy.eq(gtx.cplllock), - gtx.txuserrdy.eq(gtx.cplllock), - # TX - gtx.gttxreset.eq(reset_en & (self.reset | ~gtx.cplllock)), - # RX - gtx.gtrxreset.eq(reset_en & (self.reset | ~gtx.cplllock)), - # PLL - gtx.cpllreset.eq(self.reset | ~reset_en) - ] - # SATA TX/RX clock domains + self.comb += self.ready.eq(tx_reset_fsm.ongoing("READY") & rx_reset_fsm.ongoing("READY")) + + # Reset PLL + self.comb += gtx.cpllreset.eq(self.reset | ~reset_en) + + # Reset for SATA TX/RX clock domains self.specials += [ - AsyncResetSynchronizer(self.cd_sata_tx, ~mmcm_locked | ~gtx.txresetdone), - AsyncResetSynchronizer(self.cd_sata_rx, ~gtx.cplllock | ~gtx.rxphaligndone), - AsyncResetSynchronizer(self.cd_sata, ResetSignal("sata_tx") | ResetSignal("sata_rx")), + AsyncResetSynchronizer(self.cd_sata_tx, ~self.ready), + AsyncResetSynchronizer(self.cd_sata_rx, ~self.ready), ] # Dynamic Reconfiguration diff --git a/lib/sata/k7sataphy/ctrl.py b/lib/sata/k7sataphy/ctrl.py index f5ab206f..e2882d7a 100644 --- a/lib/sata/k7sataphy/ctrl.py +++ b/lib/sata/k7sataphy/ctrl.py @@ -20,7 +20,8 @@ def us(t, speed="SATA3"): class K7SATAPHYHostCtrl(Module): def __init__(self, gtx): - self.link_up = Signal() + self.start = Signal() + self.ready = Signal() self.speed = Signal(3) self.txdata = Signal(32) @@ -40,6 +41,12 @@ class K7SATAPHYHostCtrl(Module): self.submodules += fsm fsm.act("RESET", + gtx.txelecidle.eq(1), + If(self.start, + NextState("COMINIT") + ) + ) + fsm.act("COMINIT", txcominit.eq(1), gtx.txelecidle.eq(1), If(gtx.txcomfinish & ~gtx.rxcominitdet, @@ -114,7 +121,7 @@ class K7SATAPHYHostCtrl(Module): If(gtx.rxelecidle, NextState("RESET") ), - self.link_up.eq(1) + self.ready.eq(1) ) txcominit_d = Signal() @@ -166,7 +173,8 @@ class K7SATAPHYHostCtrl(Module): class K7SATAPHYDeviceCtrl(Module): def __init__(self, gtx): - self.link_up = Signal() + self.start = Signal() + self.ready = Signal() self.speed = Signal(3) self.txdata = Signal(32) @@ -185,11 +193,17 @@ class K7SATAPHYDeviceCtrl(Module): self.submodules += fsm fsm.act("RESET", + gtx.txelecidle.eq(1), + If(self.start, + NextState("AWAIT_COMINIT") + ) + ) + fsm.act("AWAIT_COMINIT", gtx.txelecidle.eq(1), If(gtx.rxcominitdet, NextState("COMINIT") ) - ) + ) fsm.act("COMINIT", gtx.txelecidle.eq(1), If(gtx.txcomfinish, @@ -241,7 +255,7 @@ class K7SATAPHYDeviceCtrl(Module): If(gtx.rxelecidle, NextState("RESET") ), - self.link_up.eq(1) + self.ready.eq(1) ) fsm.act("ERROR", gtx.txelecidle.eq(1),