From e0fd313ce07fcc05b1eae68348d689343600413e Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 23 Sep 2014 17:36:11 +0200 Subject: [PATCH] add data path from another design (need to be adapted to SATA specification) --- lib/sata/k7satagtx.py | 72 ++++++++++++++++++++++--------------------- lib/sata/k7sataphy.py | 70 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 36 deletions(-) diff --git a/lib/sata/k7satagtx.py b/lib/sata/k7satagtx.py index a5b9264f..20a14732 100644 --- a/lib/sata/k7satagtx.py +++ b/lib/sata/k7satagtx.py @@ -1,4 +1,5 @@ from migen.fhdl.std import * +from migen.genlib.resetsync import AsyncResetSynchronizer _K28_5 = 0b1010000011 @@ -43,9 +44,10 @@ class GTXE2_CHANNEL(Module): self.rxuserrdy = Signal() # Receive Ports - 8b10b Decoder - self.rxcharisk_out = Signal(2) - self.rxdisperr_out = Signal(2) - self.rxnotintable_out = Signal(2) + self.rxchariscomma = Signal(2) + self.rxcharisk = Signal(2) + self.rxdisperr = Signal(2) + self.rxnotintable = Signal(2) # Receive Ports - Comma Detection and Alignment self.rxmcommaalignen = Signal() @@ -74,53 +76,53 @@ class GTXE2_CHANNEL(Module): self.rxphslipmonitor = Signal(5) # Receive Ports - RX PLL Ports - self.rxresetdone_out = Signal() + self.rxresetdone = Signal() # Receive Ports - RX Ports for SATA - self.rxcominitdet_out = Signal() - self.rxcomwakedet_out = Signal() + self.rxcominitdet = Signal() + self.rxcomwakedet = Signal() # Transmit Ports - self.txuserrdy_in = Signal() + self.txuserrdy = Signal() # Transmit Ports - 8b10b Encoder Control Ports - self.txcharisk_in = Signal(2) + self.txcharisk = Signal(2) # Transmit Ports - TX Buffer and Phase Alignment Ports - self.txdlyen_in = Signal() - self.txdlysreset_in = Signal() - self.txdlysresetdone_out = Signal() - self.txphalign_in = Signal() - self.txphaligndone_out = Signal() - self.txphalignen_in = Signal() - self.txphdlyreset_in = Signal() - self.txphinit_in = Signal() - self.txphinitdone_out = Signal() + 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_in = Signal() - self.txdata_in = Signal() - self.txoutclk_out = Signal() - self.txoutclkfabric_out = Signal() - self.txoutclkpcs_out = Signal() - self.txusrclk_in = Signal() - self.txusrclk2_in = Signal() + self.gttxreset = Signal() + self.txdata = Signal() + self.txoutclk = Signal() + self.txoutclkfabric = Signal() + self.txoutclkpcs = Signal() + self.txusrclk = Signal() + self.txusrclk2 = Signal() # Transmit Ports - TX PLL Ports - self.txresetdone_out = Signal() + self.txresetdone = Signal() # Transmit Ports - TX Ports for PCI Express - self.txelecidle_in = Signal() + self.txelecidle = Signal() # Transmit Ports - TX Ports for SATA - self.txcomfinish_out = Signal() - self.txcominit_in = Signal() - self.txcomwake_in = Signal() - self.rxrate_in = Signal(3) - self.rxratedone_out = Signal() - self.txrate_in = Signal(3) - self.txratedone_out = Signal() - self.rxcdrreseT = Signal() + self.txcomfinish = Signal() + self.txcominit = Signal() + self.txcomwake = Signal() + self.rxrate = Signal(3) + self.rxratedone = Signal() + self.txrate = Signal(3) + self.txratedone = Signal() + self.rxcdrreset = Signal() self.rxlpme = Signal() # startup config @@ -644,7 +646,7 @@ class GTXE2_CHANNEL(Module): i_RXSLIDE=0, # Receive Ports - RX8B/10B Decoder Ports - #o_RXCHARISCOMMA=, + o_RXCHARISCOMMA=self.rxchariscomma, o_RXCHARISK=self.rxcharisk, # Receive Ports - Rx Channel Bonding Ports diff --git a/lib/sata/k7sataphy.py b/lib/sata/k7sataphy.py index a2cb6c75..9a8f94f9 100644 --- a/lib/sata/k7sataphy.py +++ b/lib/sata/k7sataphy.py @@ -1,6 +1,74 @@ from migen.fhdl.std import * from lib.sata.k7satagtx import SATAGTX +K28_5 = Signal(8, reset=0xBC) + class K7SATAPHY(Module): - def __init__(self, pads): + def __init__(self, pads, dw=16): self.sata_gtx = SATAGTX(pads) + + self.sink = Sink([("d", dw)], True) + self.source = Source([("d", dw)], True) + + rx_chariscomma = self.sata_gtx.channel.rxchariscomma + rx_chariscomma_d = Signal(dw//8) + rx_data = self.sata_gtx.channel.rxdata + + tx_charisk = self.sata_gtx.channel.txcharisk + tx_data = self.sata_gtx.channel.txdata + + # link ready (same chariscomma for N times) #FIXME see how to do it for SATA + self.link_ready = Signal() + link_ready_cnt = Signal(8, reset=16-1) + self.sync.sata_rx += [ + If(rx_chariscomma != 0, + If(rx_chariscomma == rx_chariscomma_d, + If(~link_ready, link_ready_cnt.eq(link_ready_cnt-1)) + ).Else( + link_ready_cnt.eq(8-1) + ), + rx_chariscomma_d.eq(rx_chariscomma) + ) + ] + self.comb += self.link_ready.eq(link_ready_cnt==0) + + # Send K28_5 on start of frame #FIXME see how to do it for SATA + self.comb += [ + If(self.sink.sop, + tx_charisk.eq(1), + tx_data.eq(Cat(K28_5, self.sink.dat[8:])) + ).Else( + tx_charisk.eq(0), + tx_data.eq(self.sink.dat) + ), + self.sink.ack.eq(1) + ] + + # Realign rx data and drive source #FIXME see how to do it for SATA + rx_data_r = Signal(dw) + rx_chariscomma_r = Signal(dw//8) + rx_data_realigned = Signal(dw) + rx_chariscomma_realigned = Signal(dw) + + self.sync += [ + rx_data_r.eq(rx_data), + rx_chariscomma_r.eq(rx_chariscomma) + ] + + cases = {} + cases[1<<0] = [ + rx_data_realigned.eq(rx_data_r[0:dw]), + rx_chariscomma_realigned.eq(rx_chariscomma_r[0:dw//8]) + ] + for i in range(1, dw//8): + cases[1<