add data path from another design (need to be adapted to SATA specification)
This commit is contained in:
parent
d55db1688b
commit
e0fd313ce0
|
@ -1,4 +1,5 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
_K28_5 = 0b1010000011
|
_K28_5 = 0b1010000011
|
||||||
|
|
||||||
|
@ -43,9 +44,10 @@ class GTXE2_CHANNEL(Module):
|
||||||
self.rxuserrdy = Signal()
|
self.rxuserrdy = Signal()
|
||||||
|
|
||||||
# Receive Ports - 8b10b Decoder
|
# Receive Ports - 8b10b Decoder
|
||||||
self.rxcharisk_out = Signal(2)
|
self.rxchariscomma = Signal(2)
|
||||||
self.rxdisperr_out = Signal(2)
|
self.rxcharisk = Signal(2)
|
||||||
self.rxnotintable_out = Signal(2)
|
self.rxdisperr = Signal(2)
|
||||||
|
self.rxnotintable = Signal(2)
|
||||||
|
|
||||||
# Receive Ports - Comma Detection and Alignment
|
# Receive Ports - Comma Detection and Alignment
|
||||||
self.rxmcommaalignen = Signal()
|
self.rxmcommaalignen = Signal()
|
||||||
|
@ -74,53 +76,53 @@ class GTXE2_CHANNEL(Module):
|
||||||
self.rxphslipmonitor = Signal(5)
|
self.rxphslipmonitor = Signal(5)
|
||||||
|
|
||||||
# Receive Ports - RX PLL Ports
|
# Receive Ports - RX PLL Ports
|
||||||
self.rxresetdone_out = Signal()
|
self.rxresetdone = Signal()
|
||||||
|
|
||||||
# Receive Ports - RX Ports for SATA
|
# Receive Ports - RX Ports for SATA
|
||||||
self.rxcominitdet_out = Signal()
|
self.rxcominitdet = Signal()
|
||||||
self.rxcomwakedet_out = Signal()
|
self.rxcomwakedet = Signal()
|
||||||
|
|
||||||
# Transmit Ports
|
# Transmit Ports
|
||||||
self.txuserrdy_in = Signal()
|
self.txuserrdy = Signal()
|
||||||
|
|
||||||
# Transmit Ports - 8b10b Encoder Control Ports
|
# Transmit Ports - 8b10b Encoder Control Ports
|
||||||
self.txcharisk_in = Signal(2)
|
self.txcharisk = Signal(2)
|
||||||
|
|
||||||
# Transmit Ports - TX Buffer and Phase Alignment Ports
|
# Transmit Ports - TX Buffer and Phase Alignment Ports
|
||||||
self.txdlyen_in = Signal()
|
self.txdlyen = Signal()
|
||||||
self.txdlysreset_in = Signal()
|
self.txdlysreset = Signal()
|
||||||
self.txdlysresetdone_out = Signal()
|
self.txdlysresetdone = Signal()
|
||||||
self.txphalign_in = Signal()
|
self.txphalign = Signal()
|
||||||
self.txphaligndone_out = Signal()
|
self.txphaligndone = Signal()
|
||||||
self.txphalignen_in = Signal()
|
self.txphalignen = Signal()
|
||||||
self.txphdlyreset_in = Signal()
|
self.txphdlyreset = Signal()
|
||||||
self.txphinit_in = Signal()
|
self.txphinit = Signal()
|
||||||
self.txphinitdone_out = Signal()
|
self.txphinitdone = Signal()
|
||||||
|
|
||||||
# Transmit Ports - TX Data Path interface
|
# Transmit Ports - TX Data Path interface
|
||||||
self.gttxreset_in = Signal()
|
self.gttxreset = Signal()
|
||||||
self.txdata_in = Signal()
|
self.txdata = Signal()
|
||||||
self.txoutclk_out = Signal()
|
self.txoutclk = Signal()
|
||||||
self.txoutclkfabric_out = Signal()
|
self.txoutclkfabric = Signal()
|
||||||
self.txoutclkpcs_out = Signal()
|
self.txoutclkpcs = Signal()
|
||||||
self.txusrclk_in = Signal()
|
self.txusrclk = Signal()
|
||||||
self.txusrclk2_in = Signal()
|
self.txusrclk2 = Signal()
|
||||||
|
|
||||||
# Transmit Ports - TX PLL Ports
|
# Transmit Ports - TX PLL Ports
|
||||||
self.txresetdone_out = Signal()
|
self.txresetdone = Signal()
|
||||||
|
|
||||||
# Transmit Ports - TX Ports for PCI Express
|
# Transmit Ports - TX Ports for PCI Express
|
||||||
self.txelecidle_in = Signal()
|
self.txelecidle = Signal()
|
||||||
|
|
||||||
# Transmit Ports - TX Ports for SATA
|
# Transmit Ports - TX Ports for SATA
|
||||||
self.txcomfinish_out = Signal()
|
self.txcomfinish = Signal()
|
||||||
self.txcominit_in = Signal()
|
self.txcominit = Signal()
|
||||||
self.txcomwake_in = Signal()
|
self.txcomwake = Signal()
|
||||||
self.rxrate_in = Signal(3)
|
self.rxrate = Signal(3)
|
||||||
self.rxratedone_out = Signal()
|
self.rxratedone = Signal()
|
||||||
self.txrate_in = Signal(3)
|
self.txrate = Signal(3)
|
||||||
self.txratedone_out = Signal()
|
self.txratedone = Signal()
|
||||||
self.rxcdrreseT = Signal()
|
self.rxcdrreset = Signal()
|
||||||
self.rxlpme = Signal()
|
self.rxlpme = Signal()
|
||||||
|
|
||||||
# startup config
|
# startup config
|
||||||
|
@ -644,7 +646,7 @@ class GTXE2_CHANNEL(Module):
|
||||||
i_RXSLIDE=0,
|
i_RXSLIDE=0,
|
||||||
|
|
||||||
# Receive Ports - RX8B/10B Decoder Ports
|
# Receive Ports - RX8B/10B Decoder Ports
|
||||||
#o_RXCHARISCOMMA=,
|
o_RXCHARISCOMMA=self.rxchariscomma,
|
||||||
o_RXCHARISK=self.rxcharisk,
|
o_RXCHARISK=self.rxcharisk,
|
||||||
|
|
||||||
# Receive Ports - Rx Channel Bonding Ports
|
# Receive Ports - Rx Channel Bonding Ports
|
||||||
|
|
|
@ -1,6 +1,74 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from lib.sata.k7satagtx import SATAGTX
|
from lib.sata.k7satagtx import SATAGTX
|
||||||
|
|
||||||
|
K28_5 = Signal(8, reset=0xBC)
|
||||||
|
|
||||||
class K7SATAPHY(Module):
|
class K7SATAPHY(Module):
|
||||||
def __init__(self, pads):
|
def __init__(self, pads, dw=16):
|
||||||
self.sata_gtx = SATAGTX(pads)
|
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)
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue