add data path from another design (need to be adapted to SATA specification)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 23 Sep 2014 15:36:11 +0000 (17:36 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 23 Sep 2014 15:36:11 +0000 (17:36 +0200)
lib/sata/k7satagtx.py
lib/sata/k7sataphy.py

index a5b9264fd3006ffaa274a1a16a86c56e62f7a3bf..20a14732818a30a6ec51c52198e3d3f7a02b1a95 100644 (file)
@@ -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
index a2cb6c75051cb0f10c36148bc6bd12ef7b043e86..9a8f94f94dc5b5f842b685d1911300e9448b3b08 100644 (file)
@@ -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<<i] = [
+                               rx_data_realigned.eq(Cat(rx_data[8*i:dw], rx_data_r[0:8*i])),
+                               rx_chariscomma_realigned.eq(Cat(rx_chariscomma[i:dw//8], rx_chariscomma_r[0:i]))
+                       ]
+               self.comb += Case(rx_chariscomma_d, cases)
+
+               self.comb += [
+                       self.source.stb.eq(link_ready),
+                       self.source.sop.eq(rx_chariscomma_realigned != 0),
+                       self.source.dat.eq(rx_data_realigned)
+               ]