diff --git a/lib/sata/k7sataphy/__init__.py b/lib/sata/k7sataphy/__init__.py index d7bca7ddb..1bcf4dec1 100644 --- a/lib/sata/k7sataphy/__init__.py +++ b/lib/sata/k7sataphy/__init__.py @@ -5,11 +5,27 @@ from lib.sata.k7sataphy.gtx import GTXE2_CHANNEL from lib.sata.k7sataphy.clocking import K7SATAPHYClocking class K7SATAPHY(Module): - def __init__(self, pads, dw=16): - self.sink = Sink([("d", dw)], True) - self.source = Source([("d", dw)], True) + def __init__(self, pads, host=True): + self.sink = Sink([("d", 32)], True) + self.source = Source([("d", 32)], True) self.submodules.gtx = GTXE2_CHANNEL(pads, "SATA3") self.submodules.clocking = K7SATAPHYClocking(pads, self.gtx) - - + if host: + self.submodules.ctrl = K7SATAPHYHostCtrl(self.gtx) + else: + self.submodules.ctrl = K7SATAPHYDeviceCtrl(self.gtx) + self.comb += [ + If(self.ctrl.link_up, + self.gtx.sink.stb.eq(self.sink.stb), + self.gtx.sink.data.eq(self.sink.data), + self.gtx.sink.charisk.eq(0), + self.sink.ack.eq(self.gtx.sink.ack), + ).Else( + self.gtx.sink.stb.eq(1), + self.gtx.sink.data.eq(self.ctrl.txdata), + self.gtx.sink.charisk.eq(self.ctrl.txcharisk), + ) + Record.connect(self.gtx.source, self.source), + self.ctrl.rxdata.eq(self.gtx.source.rxdata) + ] diff --git a/lib/sata/k7sataphy/clocking.py b/lib/sata/k7sataphy/clocking.py index 93f148fa6..2f3f4a90b 100644 --- a/lib/sata/k7sataphy/clocking.py +++ b/lib/sata/k7sataphy/clocking.py @@ -68,7 +68,7 @@ class K7SATAPHYClocking(Module): p_CLKOUT0_DIVIDE_F=4.000, p_CLKOUT0_PHASE=0.000, o_CLKOUT0=mmcm_clk0_o, # CLK1 - p_CLKOUT0_DIVIDE_F=8.000, p_CLKOUT0_PHASE=0.000, o_CLKOUT0=mmcm_clk1_o, + p_CLKOUT1_DIVIDE_F=8.000, 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), diff --git a/lib/sata/k7sataphy/ctrl.py b/lib/sata/k7sataphy/ctrl.py index e960981f7..29fd9838c 100644 --- a/lib/sata/k7sataphy/ctrl.py +++ b/lib/sata/k7sataphy/ctrl.py @@ -3,9 +3,6 @@ from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.fsm import FSM, NextState # Todo: -# it's maybe better to run this module at half the frequency? -# (to have txdata/rxdata on 32 bits) -# direct control of txdata/txcharisk, need mux for user data # rx does not use the same clock, need to resynchronize signals. def us(self, t, speed="SATA3", margin=True): @@ -24,13 +21,16 @@ class K7SATAPHYHostCtrl(Module): self.link_up = Signal() self.speed = Signal(3) + self.txdata = Signal(32) + self.txcharisk = Signal(4) + + self.rxdata = Signal(32) + align_timeout = Signal() align_detect = Signal() txcominit = Signal() txcomwake = Signa() - txdata = Signal(32) - txcharisk = Signal(4) fsm = FSM(reset_state="IDLE") self.submodules += fsm @@ -87,8 +87,8 @@ class K7SATAPHYHostCtrl(Module): ) fsm.act("AWAIT_ALIGN", gtx.txelecidle.eq(0), - txdata.eq(0x4A4A4A4A), #D10.2 - txcharisk.eq(0b0000), + self.txdata.eq(0x4A4A4A4A), #D10.2 + self.txcharisk.eq(0b0000), If(align_detect & ~align_timeout, NextState("SEND_ALIGN") ).Elif(~align_detect & align_timeout, @@ -97,44 +97,32 @@ class K7SATAPHYHostCtrl(Module): ) fsm.act("SEND_ALIGN", gtx.txelecidle.eq(0), - txdata.eq(ALIGN_VAL), - txcharisk.eq(0b0001), + self.txdata.eq(ALIGN_VAL), + self.txcharisk.eq(0b0001), If(non_align_cnt == 3, NextState("READY") ) ) fsm.act("READY", gtx.txelecidle.eq(0), - txdata.eq(SYNC_VAL), - txcharisk.eq(0b0001), + self.txdata.eq(SYNC_VAL), + self.txcharisk.eq(0b0001), If(gtx.rxelecidle, NextState("RESET") ), self.link_up.eq(1) ) - sel = Signal() - self.sync += sel.eq(~sel) - self.comb += [ - If(sel, - gtx.txdata.eq(txdata[:16]), - gtx.txcharisk.eq(txcharisk[:2]) - ).Else( - gtx.txdata.eq(txdata[16:]), - gtx.txcharisk.eq(txcharisk[2:]) - ) - ] - txcominit_d = Signal() txcomwake_d = Signal() - self.sync += [ + self.sync.sata += [ gtx.txcominit.eq(txcominit & ~txcominit_d), gtx.txcomwake.eq(txcomwake & ~txcomwake), ] - self.comb += align_detect.eq(gtx.rxdata == ALIGN_VAL); + self.comb += align_detect.eq(self.rxdata == ALIGN_VAL); align_timeout_cnt = Signal(16) - self.sync += \ + self.sync.sata += \ If(fsm.ongoing("RESET"), If(speed == 0b100, align_timeout_cnt.eq(us(873, "SATA3")) @@ -149,7 +137,7 @@ class K7SATAPHYHostCtrl(Module): self.comb += align_timeout.eq(align_timeout_cnt == 0) retry_cnt = Signal(16) - self.sync += \ + self.sync.sata += \ If(fsm.ongoing("RESET") | fsm.ongoing("AWAIT_NO_COMINIT"), If(speed == 0b100, retry_cnt.eq(us(10000, "SATA3")) @@ -163,9 +151,9 @@ class K7SATAPHYHostCtrl(Module): ) non_align_cnt = Signal(4) - self.sync += \ + self.sync.sata += \ If(fsm.ongoing("SEND_ALIGN"), - If(gtx.rxdata[7:0] == K28_5, + If(self.rxdata[7:0] == K28_5, non_align_cnt.eq(non_align_cnt + 1) ).Else( non_align_cnt.eq(0) @@ -177,13 +165,16 @@ class K7SATAPHYDeviceCtrl(Module): self.link_up = Signal() self.speed = Signal(3) + self.txdata = Signal(32) + self.txcharisk = Signal(4) + + self.rxdata = Signal(32) + align_timeout = Signal() align_detect = Signal() txcominit = Signal() txcomwake = Signa() - txdata = Signal(32) - txcharisk = Signal(4) fsm = FSM(reset_state="IDLE") self.submodules += fsm @@ -230,8 +221,8 @@ class K7SATAPHYDeviceCtrl(Module): ) fsm.act("SEND_ALIGN", gtx.txelecidle.eq(0), - txdata.eq(ALIGN_VAL), - txcharisk.eq(0b0001), + self.txdata.eq(ALIGN_VAL), + self.txcharisk.eq(0b0001), If(align_detect, NextState("READY") ).Elsif(align_timeout, @@ -239,8 +230,8 @@ class K7SATAPHYDeviceCtrl(Module): ) ) fsm.act("READY", - txdata.eq(SYNC_VAL), - txcharisk.eq(0b0001), + self.txdata.eq(SYNC_VAL), + self.txcharisk.eq(0b0001), gtx.txelecidle.eq(0), NextState("READY"), If(gtx.rxelecidle, @@ -255,14 +246,14 @@ class K7SATAPHYDeviceCtrl(Module): txcominit_d = Signal() txcomwake_d = Signal() - self.sync += [ + self.sync.sata += [ gtx.txcominit.eq(txcominit & ~txcominit_d), gtx.txcomwake.eq(txcomwake & ~txcomwake), ] - self.comb += align_detect.eq(gtx.rxdata == ALIGN_VAL); + self.comb += align_detect.eq(self.rxdata == ALIGN_VAL); align_timeout_cnt = Signal(16) - self.sync += \ + self.sync.sata += \ If(fsm.ongoing("RESET"), If(speed == 0b100, align_timeout_cnt.eq(us(55, "SATA3"))