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:
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 += [
# 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),
]
# 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),
]
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
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 *
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()
txcominit = Signal()
txcomwake = Signal()
+ self.comb += [
+ self.source.stb.eq(1),
+ self.sink.ack.eq(1)
+ ]
+
fsm = FSM(reset_state="RESET")
self.submodules += fsm
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),
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),
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()
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))
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)
+ )
)
)
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()
txcominit = Signal()
txcomwake = Signal()
+ self.comb += [
+ self.source.stb.eq(1),
+ self.sink.ack.eq(1)
+ ]
+
fsm = FSM(reset_state="RESET")
self.submodules += fsm
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")
)
)
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,
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))
###
# 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),
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)
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)
)
]
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)])
###
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
# 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),
- )
+ )
]
# Receive Ports - RX Data Path interface
self.gtrxreset = Signal()
+ self.pmarxreset = Signal()
self.rxdata = Signal(16)
self.rxoutclk = Signal()
self.rxusrclk = Signal()
# 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()
# 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)
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 = {
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()
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")
]
]
# 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()
"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,
"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",
"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",
"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,
"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,
# PCI Express Ports
#o_PHYSTATUS=,
- i_RXRATE=rxrate,
+ i_RXRATE=0,
#o_RXVALID=,
# Power-Down Ports
# Receive Ports - CDR Ports
i_RXCDRFREQRESET=0,
i_RXCDRHOLD=0,
- #o_RXCDRLOCK=,
+ o_RXCDRLOCK=rxcdrlock,
i_RXCDROVRDEN=0,
i_RXCDRRESET=0,
i_RXCDRRESETRSV=0,
# 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=,
# 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=,
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,
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,
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
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=,
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)
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
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()
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):
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)
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
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")