--- /dev/null
+from migen.fhdl.std import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
+from migen.genlib.fsm import FSM, NextState
+
+def us(self, t, speed="SATA3", margin=True):
+ clk_freq = {
+ "SATA3" : 300*1000000,
+ "SATA2" : 150*1000000,
+ "SATA1" : 75*1000000
+ }
+ clk_period_us = 1000000/clk_freq
+ if margin:
+ t += clk_period_us/2
+ return ceil(t/clk_period_us)
+
+class K7SATAPHYHostCtrl(Module):
+ def __init__(self, gtx):
+ self.link_up = Signal()
+
+ tx_com_done = Signal()
+ align_timeout = Signal()
+ align_detect = Signal()
+
+ fsm = FSM(reset_state="IDLE")
+ self.submodules += fsm
+
+ fsm.act("RESET",
+ gtx.txcominit.eq(1),
+ gtx.txelecidle.eq(1),
+ If(tx_com_done & ~gtx.rxcominitdet),
+ NextState("AWAIT_COMINIT")
+ )
+ )
+ fsm.act("AWAIT_COMINIT",
+ gtx.txelecidle.eq(1),
+ If(gtx.rxcominitdet,
+ NextState("AWAIT_NO_COMINIT")
+ ).Else(
+ If(retry_cnt == 0,
+ NextState("RESET")
+ )
+ )
+ )
+ fsm.act("AWAIT_NO_COMINIT",
+ gtx.txelecidle.eq(1),
+ If(~gtx.rxcominitdet,
+ NextState("CALIBRATE")
+ )
+ )
+ fsm.act("CALIBRATE",
+ gtx.txelecidle.eq(1),
+ NextState("COMWAKE")
+ )
+ fsm.act("COMWAKE",
+ gtx.txelecidle.eq(1),
+ gtx.txcomwake.eq(1),
+ If(tx_com_done,
+ NextState("AWAIT_COMWAKE")
+ )
+ )
+ fsm.act("AWAIT_COMWAKE",
+ gtx.txelecidle.eq(1),
+ If(gtx.rxcomwakedet,
+ NextState("AWAIT_NO_COMWAKE")
+ ).Else(
+ If(retry_cnt == 0,
+ NextState("RESET")
+ )
+ )
+ )
+ fsm.act("AWAIT_NO_COMWAKE",
+ gtx.txelecidle.eq(1),
+ If(~gtx.rxcomwakedet,
+ NextState("AWAIT_ALIGN")
+ )
+ )
+ fsm.act("AWAIT_ALIGN",
+ gtx.txelecidle.eq(0),
+ gtx.txdata.eq(0x4A4A), #D10.2
+ gtx.txcharisk.eq(0b0000),
+ If(align_detect & ~align_timeout,
+ NextState("SEND_ALIGN")
+ ).Elif(~align_detect & align_timeout,
+ NextState("RESET")
+ )
+ )
+ fsm.act("SEND_ALIGN",
+ gtx.txelecidle.eq(0),
+ gtx.txdata.eq(ALIGN_VAL),
+ gtx.txcharisk.eq(0b0001),
+ If(non_align_cnt == 3,
+ NextState("READY")
+ )
+ )
+ fsm.act("READY",
+ gtx.txelecidle.eq(0),
+ gtx.txdata.eq(SYNC_VAL),
+ gtx.txcharisk.eq(0b0001),
+ If(gtx.rxelecidle,
+ NextState("RESET")
+ ),
+ self.link_up.eq(1)
+ )
+
+class K7SATAPHYDeviceCtrl(Module):
+ def __init__(self, gtx):