From 3f7406a937e357296905e96e21982c0cc6b2b7c5 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 24 Oct 2014 19:24:05 +0200 Subject: [PATCH] various fixes and simplifications, SATA1 & SATA2 OK --- Makefile | 4 +- lib/sata/k7sataphy/crg.py | 116 +++++++------------ lib/sata/k7sataphy/ctrl.py | 109 +++++++++++------- lib/sata/k7sataphy/datapath.py | 48 ++++---- lib/sata/k7sataphy/gtx.py | 202 +++++++++++---------------------- platforms/kc705.py | 12 +- sim/compile_rtl.tcl | 2 +- targets/test.py | 119 +++++++++++++++++-- test/test_mila.py | 10 +- 9 files changed, 325 insertions(+), 297 deletions(-) diff --git a/Makefile b/Makefile index 5f343cf5..f21ec5cd 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ MSCDIR = ../misoc CURDIR = ../k7sataphy PYTHON = python3 -TOOLCHAIN = ise +TOOLCHAIN = vivado PLATFORM = kc705 PROGRAMMER = impact CMD = $(PYTHON) make.py -X $(CURDIR) -Op toolchain $(TOOLCHAIN) -Op programmer $(PROGRAMMER) -p $(PLATFORM) -t test csv: - cd $(MSCDIR) && $(CMD) --csr_csv $(CURDIR)/test/csr.csv build-csr-csv + cd $(MSCDIR) && $(CMD) --csr_csv $(CURDIR)/test/csr.csv build-csr-csv -Ot export_mila True cd $(CURDIR) bit: diff --git a/lib/sata/k7sataphy/crg.py b/lib/sata/k7sataphy/crg.py index e71339f8..5a0c2394 100644 --- a/lib/sata/k7sataphy/crg.py +++ b/lib/sata/k7sataphy/crg.py @@ -47,30 +47,30 @@ class K7SATAPHYCRG(Module): self.comb += gtx.gtrefclk0.eq(refclk) # QPLL - # not used be need to be there... see AR43339... + # not used but need to be there... see AR43339... gtx_common = GTXE2_COMMON() self.comb += [ gtx_common.refclk0.eq(refclk), gtx.qpllclk.eq(gtx_common.qpllclk), gtx.qpllrefclk.eq(gtx_common.qpllrefclk), ] + self.submodules += gtx_common # TX clocking # (SATA3) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 300MHz (16-bits) # (SATA2) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 150MHz (16-bits) # (SATA1) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 75MHz (16-bits) - # When changing rate, reconfiguration of the MMCM is needed to update the output divider. + # When changing rate, reconfiguration of the MMCM is needed to update the output divider. mmcm_reset = Signal() mmcm_locked = Signal() mmcm_drp = DRPBus() mmcm_fb = Signal() mmcm_clk_i = Signal() mmcm_clk0_o = Signal() - mmcm_clk1_o = Signal() mmcm_div_config = { - "SATA1" : 16, - "SATA2" : 8, - "SATA3" : 4 + "SATA1" : 16.0, + "SATA2" : 8.0, + "SATA3" : 4.0 } mmcm_div = mmcm_div_config[default_speed] self.specials += [ @@ -89,9 +89,6 @@ class K7SATAPHYCRG(Module): # CLK0 p_CLKOUT0_DIVIDE_F=mmcm_div, p_CLKOUT0_PHASE=0.000, o_CLKOUT0=mmcm_clk0_o, - - # CLK1 - p_CLKOUT1_DIVIDE=mmcm_div*2, p_CLKOUT1_PHASE=0.000, o_CLKOUT1=mmcm_clk1_o, ), Instance("BUFG", i_I=mmcm_clk0_o, o_O=self.cd_sata_tx.clk), ] @@ -103,7 +100,7 @@ class K7SATAPHYCRG(Module): # RX clocking # (SATA3) sata_rx recovered clk @ 300MHz from GTX RXOUTCLK # (SATA2) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK - # (SATA1) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK + # (SATA1) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK self.specials += [ Instance("BUFG", i_I=gtx.rxoutclk, o_O=self.cd_sata_rx.clk), ] @@ -119,115 +116,80 @@ class K7SATAPHYCRG(Module): clk_period_ns = 1000000000/clk_freq reset_en_cnt_max = ceil(500/clk_period_ns) reset_en_cnt = Signal(max=reset_en_cnt_max, reset=reset_en_cnt_max-1) - self.sync += If(~reset_en, reset_en_cnt.eq(reset_en_cnt-1)) + self.sync += \ + If(self.reset, + reset_en_cnt.eq(reset_en_cnt.reset) + ).Elif(~reset_en, + reset_en_cnt.eq(reset_en_cnt-1) + ) self.comb += reset_en.eq(reset_en_cnt == 0) # TX Reset FSM - tx_reset_fsm = FSM(reset_state="IDLE") + tx_reset_fsm = InsertReset(FSM(reset_state="IDLE")) self.submodules += tx_reset_fsm + self.comb += tx_reset_fsm.reset.eq(self.reset) tx_reset_fsm.act("IDLE", - gtx.txuserrdy.eq(0), - gtx.gttxreset.eq(0), - gtx.txdlysreset.eq(0), If(reset_en, - NextState("RESET_ALL"), + NextState("RESET_GTX"), ) ) - tx_reset_fsm.act("RESET_ALL", - gtx.txuserrdy.eq(0), + tx_reset_fsm.act("RESET_GTX", gtx.gttxreset.eq(1), - gtx.txdlysreset.eq(1), If(gtx.cplllock & mmcm_locked, - NextState("RELEASE_GTXRESET") + NextState("RELEASE_GTX") ) ) - tx_reset_fsm.act("RELEASE_GTXRESET", + tx_reset_fsm.act("RELEASE_GTX", 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, + If(gtx.txresetdone, 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") - ) + gtx.txuserrdy.eq(1) ) # RX Reset FSM - rx_reset_fsm = FSM(reset_state="IDLE") + rx_reset_fsm = InsertReset(FSM(reset_state="IDLE")) self.submodules += rx_reset_fsm + self.comb += rx_reset_fsm.reset.eq(self.reset) + rx_reset_fsm.act("IDLE", - gtx.rxuserrdy.eq(0), - gtx.gtrxreset.eq(0), - gtx.rxdlysreset.eq(0), If(reset_en, - NextState("RESET_ALL"), + NextState("RESET_GTX"), ) ) - rx_reset_fsm.act("RESET_ALL", - gtx.rxuserrdy.eq(0), + rx_reset_fsm.act("RESET_GTX", 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") + NextState("RELEASE_GTX") ) ) - rx_reset_fsm.act("RELEASE_DLYRESET", + rx_reset_fsm.act("RELEASE_GTX", gtx.rxuserrdy.eq(1), - gtx.gtrxreset.eq(0), - gtx.rxdlysreset.eq(0), - If(self.reset, - NextState("RESET_ALL") - ).Elif(gtx.rxdlysresetdone, + If(gtx.rxresetdone, 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") - ) + gtx.rxuserrdy.eq(1) ) # Ready - self.comb += self.ready.eq(tx_reset_fsm.ongoing("READY") & rx_reset_fsm.ongoing("READY")) + self.tx_ready = tx_reset_fsm.ongoing("READY") + self.rx_ready = rx_reset_fsm.ongoing("READY") + self.comb += self.ready.eq(self.tx_ready & self.rx_ready) # Reset PLL - self.comb += gtx.cpllreset.eq(self.reset | ~reset_en) + self.comb += gtx.cpllreset.eq(ResetSignal() | self.reset | ~reset_en) + + # Reset MMCM + self.comb += mmcm_reset.eq(ResetSignal() | self.reset | ~gtx.cplllock) # Reset for SATA TX/RX clock domains self.specials += [ - AsyncResetSynchronizer(self.cd_sata_tx, ~self.ready), - AsyncResetSynchronizer(self.cd_sata_rx, ~self.ready), + AsyncResetSynchronizer(self.cd_sata_tx, ~self.tx_ready), + AsyncResetSynchronizer(self.cd_sata_rx, ~self.rx_ready), ] # Dynamic Reconfiguration diff --git a/lib/sata/k7sataphy/ctrl.py b/lib/sata/k7sataphy/ctrl.py index d790d384..c4ffb463 100644 --- a/lib/sata/k7sataphy/ctrl.py +++ b/lib/sata/k7sataphy/ctrl.py @@ -3,6 +3,7 @@ from math import ceil from migen.fhdl.std import * from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.fsm import FSM, NextState +from migen.flow.actor import Sink, Source from lib.sata.k7sataphy.std import * @@ -14,12 +15,10 @@ class K7SATAPHYHostCtrl(Module): def __init__(self, gtx, crg, clk_freq): self.ready = Signal() - self.txdata = Signal(32) - self.txcharisk = Signal(4) + self.sink = Sink([("data", 32), ("charisk", 4)]) + self.source = Source([("data", 32), ("charisk", 4)]) - self.rxdata = Signal(32) - - align_detect = Signal() + self.align_detect = align_detect = Signal() align_timeout_cnt = Signal(32) align_timeout = Signal() @@ -31,6 +30,11 @@ class K7SATAPHYHostCtrl(Module): txcominit = Signal() txcomwake = Signal() + self.comb += [ + self.source.stb.eq(1), + self.sink.ack.eq(1) + ] + fsm = FSM(reset_state="RESET") self.submodules += fsm @@ -38,14 +42,14 @@ class K7SATAPHYHostCtrl(Module): gtx.txelecidle.eq(1), If(crg.ready, NextState("COMINIT") - ) + ), ) fsm.act("COMINIT", gtx.txelecidle.eq(1), txcominit.eq(1), If(gtx.txcomfinish & ~gtx.rxcominitdet, NextState("AWAIT_COMINIT") - ) + ), ) fsm.act("AWAIT_COMINIT", gtx.txelecidle.eq(1), @@ -55,24 +59,24 @@ class K7SATAPHYHostCtrl(Module): If(retry_timeout, 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") + NextState("COMWAKE"), ) fsm.act("COMWAKE", gtx.txelecidle.eq(1), txcomwake.eq(1), If(gtx.txcomfinish, NextState("AWAIT_COMWAKE") - ) + ), ) fsm.act("AWAIT_COMWAKE", gtx.txelecidle.eq(1), @@ -82,44 +86,48 @@ class K7SATAPHYHostCtrl(Module): If(retry_timeout, NextState("RESET") ) - ) + ), ) fsm.act("AWAIT_NO_COMWAKE", gtx.txelecidle.eq(1), If(~gtx.rxcomwakedet, - NextState("RESET_CRG") - ) + NextState("AWAIT_NO_RXELECIDLE") + ), ) - fsm.act("RESET_CRG", + fsm.act("AWAIT_NO_RXELECIDLE", gtx.txelecidle.eq(0), - crg.reset.eq(1), - NextState("AWAIT_ALIGN") + self.source.data.eq(0x4A4A4A4A), #D10.2 + self.source.charisk.eq(0b0000), + If(~gtx.rxelecidle, + NextState("AWAIT_ALIGN"), + crg.reset.eq(1), + gtx.pmarxreset.eq(1) + ), ) fsm.act("AWAIT_ALIGN", gtx.txelecidle.eq(0), - self.txdata.eq(0x4A4A4A4A), #D10.2 - self.txcharisk.eq(0b0000), + self.source.data.eq(0x4A4A4A4A), #D10.2 + self.source.charisk.eq(0b0000), gtx.rxalign.eq(1), - If(align_detect & ~align_timeout, + If((align_detect & ~gtx.rxelecidle) & ~align_timeout, NextState("SEND_ALIGN") ).Elif(~align_detect & align_timeout, NextState("RESET") - ) + ), ) fsm.act("SEND_ALIGN", gtx.txelecidle.eq(0), - self.txdata.eq(ALIGN_VAL), - self.txcharisk.eq(0b0001), + self.source.data.eq(ALIGN_VAL), + self.source.charisk.eq(0b0001), If(non_align_cnt == 3, NextState("READY") - ) + ), ) fsm.act("READY", gtx.txelecidle.eq(0), - If(gtx.rxelecidle, - NextState("RESET") - ), - self.ready.eq(1) + self.source.data.eq(SYNC_VAL), + self.source.charisk.eq(0b0001), + self.ready.eq(1), ) txcominit_d = Signal() @@ -131,7 +139,7 @@ class K7SATAPHYHostCtrl(Module): gtx.txcomwake.eq(txcomwake & ~txcomwake_d), ] - self.comb += align_detect.eq(self.rxdata == ALIGN_VAL); + self.comb += align_detect.eq(self.sink.stb & (self.sink.data == ALIGN_VAL)); self.sync += \ If(fsm.ongoing("RESET"), align_timeout_cnt.eq(us(873, clk_freq)) @@ -150,10 +158,12 @@ class K7SATAPHYHostCtrl(Module): self.sync += \ If(fsm.ongoing("SEND_ALIGN"), - If(self.rxdata[0:8] == 0xBC, - non_align_cnt.eq(non_align_cnt + 1) - ).Else( - non_align_cnt.eq(0) + If(self.sink.stb, + If(self.sink.data[0:8] == 0x7C, + non_align_cnt.eq(non_align_cnt + 1) + ).Else( + non_align_cnt.eq(0) + ) ) ) @@ -161,10 +171,8 @@ class K7SATAPHYDeviceCtrl(Module): def __init__(self, gtx, crg, clk_freq): self.ready = Signal() - self.txdata = Signal(32) - self.txcharisk = Signal(4) - - self.rxdata = Signal(32) + self.sink = Sink([("data", 32), ("charisk", 4)]) + self.source = Source([("data", 32), ("charisk", 4)]) align_detect = Signal() align_timeout = Signal() @@ -176,6 +184,11 @@ class K7SATAPHYDeviceCtrl(Module): txcominit = Signal() txcomwake = Signal() + self.comb += [ + self.source.stb.eq(1), + self.sink.ack.eq(1) + ] + fsm = FSM(reset_state="RESET") self.submodules += fsm @@ -188,6 +201,12 @@ class K7SATAPHYDeviceCtrl(Module): fsm.act("AWAIT_COMINIT", gtx.txelecidle.eq(1), If(gtx.rxcominitdet, + NextState("AWAIT_NO_COMINIT") + ) + ) + fsm.act("AWAIT_NO_COMINIT", + gtx.txelecidle.eq(1), + If(~gtx.rxcominitdet, NextState("COMINIT") ) ) @@ -222,19 +241,21 @@ class K7SATAPHYDeviceCtrl(Module): gtx.txelecidle.eq(1), txcomwake.eq(1), If(gtx.txcomfinish, - NextState("RESET_CRG") + NextState("RESET_CRG"), + crg.reset.eq(1), ) ) fsm.act("RESET_CRG", gtx.txelecidle.eq(0), - crg.reset.eq(1), - NextState("SEND_ALIGN") + If(crg.ready, + NextState("SEND_ALIGN") + ) ) fsm.act("SEND_ALIGN", gtx.txelecidle.eq(0), gtx.rxalign.eq(1), - self.txdata.eq(ALIGN_VAL), - self.txcharisk.eq(0b0001), + self.source.data.eq(ALIGN_VAL), + self.source.charisk.eq(0b0001), If(align_detect, NextState("READY") ).Elif(align_timeout, @@ -260,10 +281,10 @@ class K7SATAPHYDeviceCtrl(Module): txcominit_d.eq(txcominit), txcomwake_d.eq(txcomwake), gtx.txcominit.eq(txcominit & ~txcominit_d), - gtx.txcomwake.eq(txcomwake & ~txcomwake), + gtx.txcomwake.eq(txcomwake & ~txcomwake_d), ] - self.comb += align_detect.eq(self.rxdata == ALIGN_VAL); + self.comb += align_detect.eq(self.sink.stb & (self.sink.data == ALIGN_VAL)); self.sync += \ If(fsm.ongoing("RESET"), align_timeout_cnt.eq(us(55, clk_freq)) diff --git a/lib/sata/k7sataphy/datapath.py b/lib/sata/k7sataphy/datapath.py index 11641be3..ef06c09a 100644 --- a/lib/sata/k7sataphy/datapath.py +++ b/lib/sata/k7sataphy/datapath.py @@ -13,15 +13,15 @@ class K7SATAPHYDatapathRX(Module): ### # bytes alignment - + # shift register data_sr = Signal(32+8) charisk_sr = Signal(4+1) data_sr_d = Signal(32+8) charisk_sr_d = Signal(4+1) self.comb += [ - data_sr.eq(Cat(self.sink.payload.data, data_sr_d)), - charisk_sr.eq(Cat(self.sink.payload.charisk, charisk_sr_d)) + data_sr.eq(Cat(self.sink.data, data_sr_d)), + charisk_sr.eq(Cat(self.sink.charisk, charisk_sr_d)) ] self.sync.sata_rx += [ data_sr_d.eq(data_sr), @@ -32,8 +32,8 @@ class K7SATAPHYDatapathRX(Module): alignment = Signal() valid = Signal() self.sync.sata_rx += [ - If(self.sink.payload.charisk !=0, - alignment.eq(self.sink.payload.charisk[1]), + If(self.sink.charisk !=0, + alignment.eq(self.sink.charisk[1]), valid.eq(0) ).Else( valid.eq(~valid) @@ -64,8 +64,8 @@ class K7SATAPHYDatapathRX(Module): self.submodules.fifo = RenameClockDomains(fifo, {"write": "sata_rx", "read": "sys"}) self.comb += [ fifo.sink.stb.eq(valid), - fifo.sink.payload.data.eq(data), - fifo.sink.payload.charisk.eq(charisk), + fifo.sink.data.eq(data), + fifo.sink.charisk.eq(charisk), ] self.comb += Record.connect(fifo.source, self.source) @@ -104,14 +104,14 @@ class K7SATAPHYDatapathTX(Module): ) ] self.comb += [ - chooser(fifo.source.payload.data, mux, self.source.payload.data), - chooser(fifo.source.payload.charisk, mux, self.source.payload.charisk) + chooser(fifo.source.data, mux, self.source.data), + chooser(fifo.source.charisk, mux, self.source.charisk) ] class K7SATAPHYDatapath(Module): def __init__(self, gtx, ctrl): - self.sink = Sink([("d", 32)]) - self.source = Source([("d", 32)]) + self.sink = Sink([("data", 32), ("charisk", 4)]) + self.source = Source([("data", 32), ("charisk", 4)]) ### @@ -120,11 +120,11 @@ class K7SATAPHYDatapath(Module): tx = K7SATAPHYDatapathTX() self.submodules += rx, tx self.comb += [ - rx.sink.payload.data.eq(gtx.rxdata), - rx.sink.payload.charisk.eq(gtx.rxcharisk), + rx.sink.data.eq(gtx.rxdata), + rx.sink.charisk.eq(gtx.rxcharisk), - gtx.txdata.eq(tx.source.payload.data), - gtx.txcharisk.eq(tx.source.payload.charisk), + gtx.txdata.eq(tx.source.data), + gtx.txcharisk.eq(tx.source.charisk), ] # user / ctrl mux @@ -132,20 +132,22 @@ class K7SATAPHYDatapath(Module): # user If(ctrl.ready, tx.sink.stb.eq(self.sink.stb), - tx.sink.payload.data.eq(self.sink.payload.d), - tx.sink.payload.charisk.eq(0), + tx.sink.data.eq(self.sink.data), + tx.sink.charisk.eq(self.sink.charisk), self.sink.ack.eq(tx.sink.ack), self.source.stb.eq(rx.source.stb), - self.source.payload.d.eq(rx.source.payload.data), + self.source.data.eq(rx.source.data), + self.source.charisk.eq(rx.source.charisk), rx.source.ack.eq(1), # ctrl ).Else( - tx.sink.stb.eq(1), - tx.sink.payload.data.eq(ctrl.txdata), - tx.sink.payload.charisk.eq(ctrl.txcharisk), + tx.sink.stb.eq(ctrl.source.stb), + tx.sink.data.eq(ctrl.source.data), + tx.sink.charisk.eq(ctrl.source.charisk), - ctrl.rxdata.eq(rx.source.payload.data), + ctrl.sink.stb.eq(rx.source.stb), + ctrl.sink.data.eq(rx.source.data), rx.source.ack.eq(1), - ) + ) ] diff --git a/lib/sata/k7sataphy/gtx.py b/lib/sata/k7sataphy/gtx.py index 90b97b5b..65fff921 100644 --- a/lib/sata/k7sataphy/gtx.py +++ b/lib/sata/k7sataphy/gtx.py @@ -33,6 +33,7 @@ class K7SATAPHYGTX(Module): # Receive Ports - RX Data Path interface self.gtrxreset = Signal() + self.pmarxreset = Signal() self.rxdata = Signal(16) self.rxoutclk = Signal() self.rxusrclk = Signal() @@ -41,15 +42,6 @@ class K7SATAPHYGTX(Module): # Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR self.rxelecidle = Signal() - # Receive Ports - RX Elastic Buffer and Phase Alignment Ports - self.rxdlyen = Signal() - self.rxdlysreset = Signal() - self.rxdlysresetdone = Signal() - self.rxphalign = Signal() - self.rxphaligndone = Signal() - self.rxphalignen = Signal() - self.rxphdlyreset = Signal() - # Receive Ports - RX PLL Ports self.rxresetdone = Signal() @@ -63,17 +55,6 @@ class K7SATAPHYGTX(Module): # Transmit Ports - 8b10b Encoder Control Ports self.txcharisk = Signal(2) - # Transmit Ports - TX Buffer and Phase Alignment Ports - self.txdlyen = Signal() - self.txdlysreset = Signal() - self.txdlysresetdone = Signal() - self.txphalign = Signal() - self.txphaligndone = Signal() - self.txphalignen = Signal() - self.txphdlyreset = Signal() - self.txphinit = Signal() - self.txphinitdone = Signal() - # Transmit Ports - TX Data Path interface self.gttxreset = Signal() self.txdata = Signal(16) @@ -91,10 +72,8 @@ class K7SATAPHYGTX(Module): self.txcomfinish = Signal() self.txcominit = Signal() self.txcomwake = Signal() - self.rxrate = Signal(3) - self.rxratedone = Signal() self.txrate = Signal(3) - self.txratedone = Signal() + self.rxcdrlock = Signal() # Config at startup div_config = { @@ -108,19 +87,13 @@ class K7SATAPHYGTX(Module): cdr_config = { "SATA1" : 0x0380008BFF40100008, "SATA2" : 0x0380008BFF40200008, - "SATA3" : 0X0380008BFF20200010 + "SATA3" : 0X0380008BFF10200010 } rxcdr_cfg = cdr_config[default_speed] # Internals and clock domain crossing # sys_clk --> sata_tx clk txuserrdy = Signal() - txdlyen = Signal() - txdlysreset = Signal() - txphalign = Signal() - txphalignen = Signal() - txphdlyreset = Signal() - txphinit = Signal() txelecidle = Signal(reset=1) txcominit = Signal() txcomwake = Signal() @@ -128,11 +101,6 @@ class K7SATAPHYGTX(Module): self.specials += [ MultiReg(self.txuserrdy, txuserrdy, "sata_tx"), - MultiReg(self.txdlyen, txdlyen, "sata_tx"), - MultiReg(self.txdlysreset, txdlysreset, "sata_tx"), - MultiReg(self.txphalign, txphalign, "sata_tx"), - MultiReg(self.txphalignen, txphalignen, "sata_tx"), - MultiReg(self.txphdlyreset, txphdlyreset, "sata_tx"), MultiReg(self.txelecidle, txelecidle, "sata_tx"), MultiReg(self.txrate, txrate, "sata_tx") ] @@ -142,92 +110,58 @@ class K7SATAPHYGTX(Module): ] # sata_tx clk --> sys clk - txdlysresetdone = Signal() - txphaligndone = Signal() - txphinitdone = Signal() txresetdone = Signal() - txratedone = Signal() txcomfinish = Signal() self.specials += [ - MultiReg(txdlysresetdone, self.txdlysresetdone, "sys"), - MultiReg(txphaligndone, self.txphaligndone, "sys"), - MultiReg(txphinitdone, self.txphinitdone, "sys"), MultiReg(txresetdone, self.txresetdone, "sys"), - MultiReg(txratedone, self.txratedone, "sys"), ] self.submodules += [ _PulseSynchronizer(txcomfinish, "sata_tx", self.txcomfinish, "sys"), - ] + ] # sys clk --> sata_rx clk rxuserrdy = Signal() - rxelecidle = Signal() - rxdlyen = Signal() - rxdlysreset = Signal() - rxphalign = Signal() - rxphalignen = Signal() - rxphdlyreset = Signal() - rxrate = Signal(3) - rxalign = Signal() self.specials += [ MultiReg(self.rxuserrdy, rxuserrdy, "sata_rx"), - MultiReg(self.rxelecidle, rxelecidle, "sata_rx"), - MultiReg(self.rxdlyen, rxdlyen, "sata_rx"), - MultiReg(self.rxdlysreset, rxdlysreset, "sata_rx"), - MultiReg(self.rxphalign, rxphalign, "sata_rx"), - MultiReg(self.rxphalignen, rxphalignen, "sata_rx"), - MultiReg(self.rxphdlyreset, rxphdlyreset, "sata_rx"), - MultiReg(self.rxrate, rxrate, "sata_rx"), - MultiReg(self.rxalign, rxalign, "sata_rx"), ] - # sata_rx clk --> sys clk - rxdlysresetdone = Signal() - rxphaligndone = Signal() + rxelecidle = Signal() + rxelecidle_i = Signal() + rxelecidle_cnt_i = Signal(9) rxresetdone = Signal() rxcominitdet = Signal() rxcomwakedet = Signal() rxratedone = Signal() + rxcdrlock = Signal() self.specials += [ - MultiReg(rxdlysresetdone, self.rxdlysresetdone, "sys"), - MultiReg(rxphaligndone, self.rxphaligndone, "sys"), + MultiReg(rxelecidle, rxelecidle_i, "sys"), MultiReg(rxresetdone, self.rxresetdone, "sys"), - MultiReg(rxratedone, self.rxratedone, "sys") + MultiReg(rxcominitdet, self.rxcominitdet, "sys"), + MultiReg(rxcomwakedet, self.rxcomwakedet, "sys"), + MultiReg(rxcdrlock, self.rxcdrlock, "sys"), ] - self.submodules += [ - _PulseSynchronizer(rxcominitdet, "sata_rx", self.rxcominitdet, "sys"), - _PulseSynchronizer(rxcomwakedet, "sata_rx", self.rxcomwakedet, "sys"), - ] - - - self.rxbyteisaligned = Signal() - self.rxbyterealign = Signal() - self.rxcommadet = Signal() - - # Bypass TX buffer - self.comb += [ - self.txphdlyreset.eq(0), - self.txphalignen.eq(0), - self.txdlyen.eq(0), - self.txphalign.eq(0), - self.txphinit.eq(0) + self.sync += [ + If(rxelecidle_i != self.rxelecidle, + If(rxelecidle_cnt_i == 0, + self.rxelecidle.eq(rxelecidle_i), + rxelecidle_cnt_i.eq(255) + ).Else( + rxelecidle_cnt_i.eq(rxelecidle_cnt_i-1) + ) + ).Else( + rxelecidle_cnt_i.eq(255) + ) ] - # Bypass RX buffer - self.comb += [ - self.rxphdlyreset.eq(0), - self.rxdlyen.eq(0), - self.rxphalign.eq(0), - self.rxphalignen.eq(0), - ] + self.rxbyteisaligned = Signal() - # QPLL input clock + # QPLL input clock self.qpllclk = Signal() self.qpllrefclk = Signal() @@ -263,18 +197,16 @@ class K7SATAPHYGTX(Module): "p_CBCC_DATA_SOURCE_SEL":"DECODED", "p_CLK_COR_SEQ_2_USE":"FALSE", "p_CLK_COR_KEEP_IDLE":"FALSE", - "p_CLK_COR_MAX_LAT":9, - "p_CLK_COR_MIN_LAT":7, + "p_CLK_COR_MAX_LAT":35, + "p_CLK_COR_MIN_LAT":28, "p_CLK_COR_PRECEDENCE":"TRUE", "p_CLK_COR_REPEAT_WAIT":0, - "p_CLK_COR_SEQ_LEN":1, + "p_CLK_COR_SEQ_LEN":4, "p_CLK_COR_SEQ_1_ENABLE":ones(4), - "p_CLK_COR_SEQ_1_ENABLE":0, - "p_CLK_COR_SEQ_1_1":0, - "p_CLK_COR_SEQ_1_1":0, - "p_CLK_COR_SEQ_1_2":0, - "p_CLK_COR_SEQ_1_3":0, - "p_CLK_COR_SEQ_1_4":0, + "p_CLK_COR_SEQ_1_1":0b0110111100, + "p_CLK_COR_SEQ_1_2":0b0001001010, + "p_CLK_COR_SEQ_1_3":0b0001001010, + "p_CLK_COR_SEQ_1_4":0b0001111011, "p_CLK_CORRECT_USE":"FALSE", "p_CLK_COR_SEQ_2_ENABLE":ones(4), "p_CLK_COR_SEQ_2_1":0, @@ -346,7 +278,7 @@ class K7SATAPHYGTX(Module): "p_RXBUF_ADDR_MODE":"FAST", "p_RXBUF_EIDLE_HI_CNT":0b1000, "p_RXBUF_EIDLE_LO_CNT":0, - "p_RXBUF_EN":"FALSE", + "p_RXBUF_EN":"TRUE", "p_RX_BUFFER_CFG":0, "p_RXBUF_RESET_ON_CB_CHANGE":"TRUE", "p_RXBUF_RESET_ON_COMMAALIGN":"FALSE", @@ -362,7 +294,7 @@ class K7SATAPHYGTX(Module): "p_RXPH_CFG":0, "p_RXPHDLY_CFG":0x084820, "p_RXPH_MONITOR_SEL":0, - "p_RX_XCLK_SEL":"RXUSR", + "p_RX_XCLK_SEL":"RXREC", "p_RX_DDI_SEL":0, "p_RX_DEFER_RESET_BUF_EN":"TRUE", @@ -412,15 +344,15 @@ class K7SATAPHYGTX(Module): "p_TRANS_TIME_RATE":0x0e, # TX Buffer Attributes - "p_TXBUF_EN":"FALSE", - "p_TXBUF_RESET_ON_RATE_CHANGE":"FALSE", + "p_TXBUF_EN":"TRUE", + "p_TXBUF_RESET_ON_RATE_CHANGE":"TRUE", "p_TXDLY_CFG":0x1f, "p_TXDLY_LCFG":0x030, "p_TXDLY_TAP_CFG":0, "p_TXPH_CFG":0x0780, "p_TXPHDLY_CFG":0x084020, "p_TXPH_MONITOR_SEL":0, - "p_TX_XCLK_SEL":"TXUSR", + "p_TX_XCLK_SEL":"TXOUT", # FPGA TX Interface Attributes "p_TX_DATA_WIDTH":20, @@ -479,7 +411,7 @@ class K7SATAPHYGTX(Module): "p_RX_DFE_H5_CFG":0b00011100000, "p_RX_DFE_KL_CFG":0b0000011111110, "p_RX_DFE_LPM_CFG":0x0954, - "p_RX_DFE_LPM_HOLD_DURING_EIDLE":1, + "p_RX_DFE_LPM_HOLD_DURING_EIDLE":0, "p_RX_DFE_UT_CFG":0b10001111000000000, "p_RX_DFE_VP_CFG":0b00011111100000011, @@ -562,7 +494,7 @@ class K7SATAPHYGTX(Module): # PCI Express Ports #o_PHYSTATUS=, - i_RXRATE=rxrate, + i_RXRATE=0, #o_RXVALID=, # Power-Down Ports @@ -584,7 +516,7 @@ class K7SATAPHYGTX(Module): # Receive Ports - CDR Ports i_RXCDRFREQRESET=0, i_RXCDRHOLD=0, - #o_RXCDRLOCK=, + o_RXCDRLOCK=rxcdrlock, i_RXCDROVRDEN=0, i_RXCDRRESET=0, i_RXCDRRESETRSV=0, @@ -625,17 +557,17 @@ class K7SATAPHYGTX(Module): # Receive Ports - RX Buffer Bypass Ports i_RXBUFRESET=0, #o_RXBUFSTATUS=, - i_RXDDIEN=1, - i_RXDLYBYPASS=0, - i_RXDLYEN=rxdlyen, + i_RXDDIEN=0, + i_RXDLYBYPASS=1, + i_RXDLYEN=0, i_RXDLYOVRDEN=0, - i_RXDLYSRESET=rxdlysreset, - o_RXDLYSRESETDONE=rxdlysresetdone, - i_RXPHALIGN=rxphalign, - o_RXPHALIGNDONE=rxphaligndone, - i_RXPHALIGNEN=rxphalignen, + i_RXDLYSRESET=0, + #o_RXDLYSRESETDONE=0, + i_RXPHALIGN=0, + #o_RXPHALIGNDONE=, + i_RXPHALIGNEN=0, i_RXPHDLYPD=0, - i_RXPHDLYRESET=rxphdlyreset, + i_RXPHDLYRESET=0, #o_RXPHMONITOR=, i_RXPHOVRDEN=0, #o_RXPHSLIPMONITOR=, @@ -643,11 +575,11 @@ class K7SATAPHYGTX(Module): # Receive Ports - RX Byte and Word Alignment Ports o_RXBYTEISALIGNED=self.rxbyteisaligned, - o_RXBYTEREALIGN=self.rxbyterealign, - o_RXCOMMADET=self.rxcommadet, + #o_RXBYTEREALIGN=, + #o_RXCOMMADET=, i_RXCOMMADETEN=1, - i_RXMCOMMAALIGNEN=rxalign, - i_RXPCOMMAALIGNEN=rxalign, + i_RXMCOMMAALIGNEN=1, + i_RXPCOMMAALIGNEN=1, # Receive Ports - RX Channel Bonding Ports #o_RXCHANBONDSEQ=, @@ -693,7 +625,7 @@ class K7SATAPHYGTX(Module): i_RXLPMLFHOLD=0, # Receive Ports - RX Fabric ClocK Output Control Ports - o_RXRATEDONE=rxratedone, + #o_RXRATEDONE=, # Receive Ports - RX Fabric Output Control Ports o_RXOUTCLK=self.rxoutclk, @@ -714,7 +646,7 @@ class K7SATAPHYGTX(Module): i_GTRXRESET=self.gtrxreset, i_RXOOBRESET=0, i_RXPCSRESET=0, - i_RXPMARESET=0, + i_RXPMARESET=self.pmarxreset, # Receive Ports - RX Margin Analysis ports i_RXLPMEN=0, @@ -791,20 +723,20 @@ class K7SATAPHYGTX(Module): i_TXPRBSFORCEERR=0, # Transmit Ports - TX Buffer Bypass Ports - i_TXDLYBYPASS=0, - i_TXDLYEN=txdlyen, + i_TXDLYBYPASS=1, + i_TXDLYEN=0, i_TXDLYHOLD=0, i_TXDLYOVRDEN=0, - i_TXDLYSRESET=txdlysreset, - o_TXDLYSRESETDONE=txdlysresetdone, + i_TXDLYSRESET=0, + #o_TXDLYSRESETDONE=, i_TXDLYUPDOWN=0, - i_TXPHALIGN=txphalign, - o_TXPHALIGNDONE=txphaligndone, - i_TXPHALIGNEN=txphalignen, + i_TXPHALIGN=0, + #o_TXPHALIGNDONE=txphaligndone, + i_TXPHALIGNEN=0, i_TXPHDLYPD=0, - i_TXPHDLYRESET=txphdlyreset, - i_TXPHINIT=txphinit, - o_TXPHINITDONE=txphinitdone, + i_TXPHDLYRESET=0, + i_TXPHINIT=0, + #o_TXPHINITDONE=, i_TXPHOVRDEN=0, # Transmit Ports - TX Buffer Ports @@ -830,8 +762,8 @@ class K7SATAPHYGTX(Module): o_TXOUTCLK=self.txoutclk, #o_TXOUTCLKFABRIC=, #o_TXOUTCLKPCS=, - i_TXOUTCLKSEL=0b11, - o_TXRATEDONE=txratedone, + i_TXOUTCLKSEL=0b11, #?? + #o_TXRATEDONE=, # Transmit Ports - TX Gearbox Ports i_TXCHARISK=self.txcharisk, #o_TXGEARBOXREADY=, diff --git a/platforms/kc705.py b/platforms/kc705.py index 45e7bd14..c1886710 100644 --- a/platforms/kc705.py +++ b/platforms/kc705.py @@ -116,5 +116,15 @@ def Platform(*args, toolchain="vivado", programmer="xc3sprog", **kwargs): try: self.add_period_constraint(self.lookup_request("clk200").p, 5.0) except ConstraintError: - pass + pass + try: + self.add_period_constraint(self.lookup_request("sata_host").refclk_p, 6.66) + except ConstraintError: + pass + self.add_platform_command(""" +create_clock -name sys_clk -period 6 [get_nets sys_clk] +create_clock -name sata_rx_clk -period 3.33 [get_nets sata_rx_clk] +create_clock -name sata_tx_clk -period 3.33 [get_nets sata_tx_clk] +""") + return RealPlatform(*args, **kwargs) diff --git a/sim/compile_rtl.tcl b/sim/compile_rtl.tcl index 1daeb27a..dba9f4a1 100644 --- a/sim/compile_rtl.tcl +++ b/sim/compile_rtl.tcl @@ -7,5 +7,5 @@ set HDL_WORK "work" hdl_compile -v 2005 { - ../../misoc/build/testdesign-kc705_impact.v + ../../misoc/build/simdesign-kc705.v } \ No newline at end of file diff --git a/targets/test.py b/targets/test.py index 9e2ccef1..cd51ca2b 100644 --- a/targets/test.py +++ b/targets/test.py @@ -3,12 +3,16 @@ from migen.bank import csrgen from migen.bus import wishbone, csr from migen.bus import wishbone2csr from migen.genlib.resetsync import AsyncResetSynchronizer +from migen.bank.description import * from miscope.uart2wishbone import UART2Wishbone from misoclib import identifier +from lib.sata.k7sataphy.std import * from lib.sata.k7sataphy import K7SATAPHY +from migen.genlib.cdc import * + class _CRG(Module): def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() @@ -42,7 +46,7 @@ class _CRG(Module): p_CLKOUT4_DIVIDE=2, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4= ), Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset")), ] class UART2WB(Module): @@ -86,10 +90,10 @@ class UART2WB(Module): data_width=self.csr_data_width) self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses()) -class TestDesign(UART2WB): +class SimDesign(UART2WB): default_platform = "kc705" - def __init__(self, platform, simulation=False): + def __init__(self, platform, export_mila=False): clk_freq = 166666*1000 UART2WB.__init__(self, platform, clk_freq) self.submodules.crg = _CRG(platform) @@ -97,13 +101,104 @@ class TestDesign(UART2WB): self.submodules.sataphy_host = K7SATAPHY(platform.request("sata_host"), clk_freq, host=True) self.comb += [ self.sataphy_host.sink.stb.eq(1), - self.sataphy_host.sink.payload.d.eq(0x12345678) + self.sataphy_host.sink.data.eq(SYNC_VAL), + self.sataphy_host.sink.charisk.eq(0b0001) + ] + self.submodules.sataphy_device = K7SATAPHY(platform.request("sata_device"), clk_freq, host=False) + self.comb += [ + self.sataphy_device.sink.stb.eq(1), + self.sataphy_device.sink.data.eq(SYNC_VAL), + self.sataphy_device.sink.charisk.eq(0b0001) + ] + + +class ClockLeds(Module): + def __init__(self, platform): + led_sata_rx = platform.request("user_led", 0) + led_sata_tx = platform.request("user_led", 1) + + sata_rx_cnt = Signal(32) + sata_tx_cnt = Signal(32) + + self.sync.sata_rx += \ + If(sata_rx_cnt == 0, + led_sata_rx.eq(~led_sata_rx), + sata_rx_cnt.eq(150*1000*1000//2) + ).Else( + sata_rx_cnt.eq(sata_rx_cnt-1) + ) + + self.sync.sata_tx += \ + If(sata_tx_cnt == 0, + led_sata_tx.eq(~led_sata_tx), + sata_tx_cnt.eq(150*1000*1000//2) + ).Else( + sata_tx_cnt.eq(sata_tx_cnt-1) + ) + +class TestDesign(UART2WB, AutoCSR): + default_platform = "kc705" + csr_map = { + "mila": 10, + } + csr_map.update(UART2WB.csr_map) + + def __init__(self, platform, mila=True, export_mila=False): + clk_freq = 166666*1000 + UART2WB.__init__(self, platform, clk_freq) + self.submodules.crg = _CRG(platform) + + self.submodules.sataphy_host = K7SATAPHY(platform.request("sata_host"), clk_freq, host=True, default_speed="SATA2") + self.comb += [ + self.sataphy_host.sink.stb.eq(1), + self.sataphy_host.sink.data.eq(SYNC_VAL), + self.sataphy_host.sink.charisk.eq(0b0001) ] - if simulation: - self.submodules.sataphy_device = K7SATAPHY(platform.request("sata_device"), clk_freq, host=False) - self.comb += [ - self.sataphy_device.sink.stb.eq(1), - self.sataphy_device.sink.payload.d.eq(0x12345678) - ] - -default_subtarget = TestDesign + + self.submodules.clock_leds = ClockLeds(platform) + + if mila: + import os + from miscope import MiLa, Term, UART2Wishbone + + gtx = self.sataphy_host.gtx + ctrl = self.sataphy_host.ctrl + crg = self.sataphy_host.crg + + debug = ( + gtx.rxresetdone, + gtx.txresetdone, + + gtx.rxuserrdy, + gtx.txuserrdy, + + gtx.rxelecidle, + gtx.rxcominitdet, + gtx.rxcomwakedet, + + gtx.txcomfinish, + gtx.txcominit, + gtx.txcomwake, + + ctrl.sink.stb, + ctrl.sink.data, + ctrl.sink.charisk, + ctrl.align_detect, + + self.sataphy_host.source.stb, + self.sataphy_host.source.data, + self.sataphy_host.source.charisk, + ) + + self.comb += platform.request("user_led", 2).eq(crg.ready) + self.comb += platform.request("user_led", 3).eq(ctrl.ready) + + self.submodules.mila = MiLa(depth=512, dat=Cat(*debug)) + self.mila.add_port(Term) + + if export_mila: + mila_filename = os.path.join(platform.soc_ext_path, "test", "mila.csv") + self.mila.export(self, debug, mila_filename) + +#default_subtarget = SimDesign +default_subtarget = TestDesign \ No newline at end of file diff --git a/test/test_mila.py b/test/test_mila.py index 2aed4403..9c578c50 100644 --- a/test/test_mila.py +++ b/test/test_mila.py @@ -4,8 +4,14 @@ from miscope.host.drivers import MiLaDriver mila = MiLaDriver(wb.regs, "mila", use_rle=False) wb.open() ### -trigger0 = mila.sataphy_host_gtx_txcominit0_o -mask0 = mila.sataphy_host_gtx_txcominit0_m +trigger0 = mila.gtx_rxelecidle0_o*0 +mask0 = mila.gtx_rxelecidle0_m + +#trigger0 = mila.ctrl_align_detect_o +#mask0 = mila.ctrl_align_detect_m + +trigger0 = 0 +mask0 = 0 mila.prog_term(port=0, trigger=trigger0, mask=mask0) mila.prog_sum("term") -- 2.30.2