add tx_reset_fsm and rx_reset_fsm
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 27 Sep 2014 14:10:39 +0000 (16:10 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 27 Sep 2014 14:10:39 +0000 (16:10 +0200)
lib/sata/k7sataphy/__init__.py
lib/sata/k7sataphy/crg.py
lib/sata/k7sataphy/ctrl.py

index d985b0cc6027976a50eb50d54f9e2ee8211c495f..8bcd029b0d877cd26e278ede8c7c004fb7c311bf 100644 (file)
@@ -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),
index df14b5f21fb216ff4a355d245d196470b3ce1eba..82ac4f7e5cf95472157f2be2d66cc453fd4b7d89 100644 (file)
@@ -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
index f5ab206f1d27f4373576fa384d22931686001b06..e2882d7a520aab957f9559d3657cd26b35d29586 100644 (file)
@@ -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),