fix alignment (still some transmissions errors --> need to check clocks and resets)
This commit is contained in:
parent
ed752758b0
commit
b47153fbfa
|
@ -5,7 +5,6 @@ from lib.sata.k7sataphy.std import *
|
||||||
from lib.sata.k7sataphy.gtx import K7SATAPHYGTX
|
from lib.sata.k7sataphy.gtx import K7SATAPHYGTX
|
||||||
from lib.sata.k7sataphy.crg import K7SATAPHYCRG
|
from lib.sata.k7sataphy.crg import K7SATAPHYCRG
|
||||||
from lib.sata.k7sataphy.ctrl import K7SATAPHYHostCtrl, K7SATAPHYDeviceCtrl
|
from lib.sata.k7sataphy.ctrl import K7SATAPHYHostCtrl, K7SATAPHYDeviceCtrl
|
||||||
from lib.sata.k7sataphy.datapath import K7SATAPHYRXAlign
|
|
||||||
from lib.sata.k7sataphy.datapath import K7SATAPHYRXConvert, K7SATAPHYTXConvert
|
from lib.sata.k7sataphy.datapath import K7SATAPHYRXConvert, K7SATAPHYTXConvert
|
||||||
|
|
||||||
class K7SATAPHY(Module):
|
class K7SATAPHY(Module):
|
||||||
|
@ -20,22 +19,18 @@ class K7SATAPHY(Module):
|
||||||
# CRG / CTRL
|
# CRG / CTRL
|
||||||
crg = K7SATAPHYCRG(pads, gtx, clk_freq, default_speed)
|
crg = K7SATAPHYCRG(pads, gtx, clk_freq, default_speed)
|
||||||
if host:
|
if host:
|
||||||
ctrl = K7SATAPHYHostCtrl(gtx, clk_freq)
|
ctrl = K7SATAPHYHostCtrl(gtx, crg, clk_freq)
|
||||||
else:
|
else:
|
||||||
ctrl = K7SATAPHYDeviceCtrl(gtx, clk_freq)
|
ctrl = K7SATAPHYDeviceCtrl(gtx, crg, clk_freq)
|
||||||
self.submodules += crg, ctrl
|
self.submodules += crg, ctrl
|
||||||
self.comb += ctrl.start.eq(crg.ready)
|
|
||||||
|
|
||||||
# DATAPATH
|
# DATAPATH
|
||||||
rxalign = K7SATAPHYRXAlign()
|
|
||||||
rxconvert = K7SATAPHYRXConvert()
|
rxconvert = K7SATAPHYRXConvert()
|
||||||
txconvert = K7SATAPHYTXConvert()
|
txconvert = K7SATAPHYTXConvert()
|
||||||
self.submodules += rxalign, rxconvert, txconvert
|
self.submodules += rxconvert, txconvert
|
||||||
self.comb += [
|
self.comb += [
|
||||||
rxalign.rxdata_i.eq(gtx.rxdata),
|
rxconvert.rxdata.eq(gtx.rxdata),
|
||||||
rxalign.rxcharisk_i.eq(gtx.rxcharisk),
|
rxconvert.rxcharisk.eq(gtx.rxcharisk),
|
||||||
rxconvert.rxdata.eq(rxalign.rxdata_o),
|
|
||||||
rxconvert.rxcharisk.eq(rxalign.rxcharisk_o),
|
|
||||||
|
|
||||||
gtx.txdata.eq(txconvert.txdata),
|
gtx.txdata.eq(txconvert.txdata),
|
||||||
gtx.txcharisk.eq(txconvert.txcharisk)
|
gtx.txcharisk.eq(txconvert.txcharisk)
|
||||||
|
@ -53,7 +48,7 @@ class K7SATAPHY(Module):
|
||||||
txconvert.sink.charisk.eq(ctrl.txcharisk)
|
txconvert.sink.charisk.eq(ctrl.txcharisk)
|
||||||
),
|
),
|
||||||
self.source.stb.eq(rxconvert.source.stb),
|
self.source.stb.eq(rxconvert.source.stb),
|
||||||
self.source.payload.eq(rxconvert.source.payload),
|
self.source.payload.eq(rxconvert.source.data),
|
||||||
rxconvert.source.ack.eq(self.source.ack),
|
rxconvert.source.ack.eq(1),
|
||||||
ctrl.rxdata.eq(rxconvert.source.data)
|
ctrl.rxdata.eq(rxconvert.source.data)
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,8 +11,7 @@ def us(t, clk_freq):
|
||||||
return ceil(t/clk_period_us)
|
return ceil(t/clk_period_us)
|
||||||
|
|
||||||
class K7SATAPHYHostCtrl(Module):
|
class K7SATAPHYHostCtrl(Module):
|
||||||
def __init__(self, gtx, clk_freq):
|
def __init__(self, gtx, crg, clk_freq):
|
||||||
self.start = Signal()
|
|
||||||
self.ready = Signal()
|
self.ready = Signal()
|
||||||
|
|
||||||
self.txdata = Signal(32)
|
self.txdata = Signal(32)
|
||||||
|
@ -33,7 +32,7 @@ class K7SATAPHYHostCtrl(Module):
|
||||||
|
|
||||||
fsm.act("RESET",
|
fsm.act("RESET",
|
||||||
gtx.txelecidle.eq(1),
|
gtx.txelecidle.eq(1),
|
||||||
If(self.start,
|
If(crg.ready,
|
||||||
NextState("COMINIT")
|
NextState("COMINIT")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -89,8 +88,7 @@ class K7SATAPHYHostCtrl(Module):
|
||||||
)
|
)
|
||||||
fsm.act("AWAIT_ALIGN",
|
fsm.act("AWAIT_ALIGN",
|
||||||
gtx.txelecidle.eq(0),
|
gtx.txelecidle.eq(0),
|
||||||
self.txdata.eq(0x4A4A4A4A), #D10.2
|
gtx.rxalign.eq(1),
|
||||||
self.txcharisk.eq(0b0000),
|
|
||||||
If(align_detect & ~align_timeout,
|
If(align_detect & ~align_timeout,
|
||||||
NextState("SEND_ALIGN")
|
NextState("SEND_ALIGN")
|
||||||
).Elif(~align_detect & align_timeout,
|
).Elif(~align_detect & align_timeout,
|
||||||
|
@ -143,7 +141,7 @@ class K7SATAPHYHostCtrl(Module):
|
||||||
|
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If(fsm.ongoing("SEND_ALIGN"),
|
If(fsm.ongoing("SEND_ALIGN"),
|
||||||
If(self.rxdata[0:8] == K28_5,
|
If(self.rxdata[0:8] == 0xBC,
|
||||||
non_align_cnt.eq(non_align_cnt + 1)
|
non_align_cnt.eq(non_align_cnt + 1)
|
||||||
).Else(
|
).Else(
|
||||||
non_align_cnt.eq(0)
|
non_align_cnt.eq(0)
|
||||||
|
@ -151,8 +149,7 @@ class K7SATAPHYHostCtrl(Module):
|
||||||
)
|
)
|
||||||
|
|
||||||
class K7SATAPHYDeviceCtrl(Module):
|
class K7SATAPHYDeviceCtrl(Module):
|
||||||
def __init__(self, gtx, clk_freq):
|
def __init__(self, gtx, crg, clk_freq):
|
||||||
self.start = Signal()
|
|
||||||
self.ready = Signal()
|
self.ready = Signal()
|
||||||
|
|
||||||
self.txdata = Signal(32)
|
self.txdata = Signal(32)
|
||||||
|
@ -172,7 +169,7 @@ class K7SATAPHYDeviceCtrl(Module):
|
||||||
|
|
||||||
fsm.act("RESET",
|
fsm.act("RESET",
|
||||||
gtx.txelecidle.eq(1),
|
gtx.txelecidle.eq(1),
|
||||||
If(self.start,
|
If(crg.ready,
|
||||||
NextState("AWAIT_COMINIT")
|
NextState("AWAIT_COMINIT")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -218,6 +215,7 @@ class K7SATAPHYDeviceCtrl(Module):
|
||||||
)
|
)
|
||||||
fsm.act("SEND_ALIGN",
|
fsm.act("SEND_ALIGN",
|
||||||
gtx.txelecidle.eq(0),
|
gtx.txelecidle.eq(0),
|
||||||
|
gtx.rxalign.eq(1),
|
||||||
self.txdata.eq(ALIGN_VAL),
|
self.txdata.eq(ALIGN_VAL),
|
||||||
self.txcharisk.eq(0b0001),
|
self.txcharisk.eq(0b0001),
|
||||||
If(align_detect,
|
If(align_detect,
|
||||||
|
|
|
@ -5,69 +5,57 @@ from migen.flow.actor import Sink, Source
|
||||||
|
|
||||||
from lib.sata.k7sataphy.std import *
|
from lib.sata.k7sataphy.std import *
|
||||||
|
|
||||||
class K7SATAPHYRXAlign(Module):
|
class K7SATAPHYRXConvert(Module):
|
||||||
def __init__(self, dw=16):
|
def __init__(self, dw=16):
|
||||||
self.rxdata_i = Signal(dw)
|
self.rxdata = Signal(dw)
|
||||||
self.rxcharisk_i = Signal(dw//8)
|
self.rxcharisk = Signal(dw//8)
|
||||||
|
|
||||||
self.rxdata_o = Signal(dw)
|
self.source = Source([("data", 32), ("charisk", 4)])
|
||||||
self.rxcharisk_o = Signal(dw//8)
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
rxdata_r = Signal(dw)
|
# byte alignment
|
||||||
rxcharisk_r = Signal(dw//8)
|
rxdata_r = Signal(2*dw)
|
||||||
|
rxcharisk_r = Signal((2*dw)//8)
|
||||||
|
rxalignment = Signal(dw//8)
|
||||||
|
rxvalid = Signal()
|
||||||
self.sync.sata_rx += [
|
self.sync.sata_rx += [
|
||||||
rxdata_r.eq(self.rxdata_i),
|
rxdata_r.eq(Cat(self.rxdata, rxdata_r[0:dw])),
|
||||||
rxcharisk_r.eq(self.rxcharisk_i)
|
rxcharisk_r.eq(Cat(self.rxcharisk, rxcharisk_r[0:dw//8])),
|
||||||
|
If(self.rxcharisk != 0,
|
||||||
|
rxalignment.eq(self.rxcharisk),
|
||||||
|
rxvalid.eq(1)
|
||||||
|
).Else(
|
||||||
|
rxvalid.eq(~rxvalid)
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
rxdata = Signal(2*dw)
|
||||||
|
rxcharisk = Signal((2*dw)//8)
|
||||||
cases = {}
|
cases = {}
|
||||||
cases[1<<0] = [
|
cases[1<<0] = [
|
||||||
self.rxdata_o.eq(rxdata_r[0:dw]),
|
rxdata.eq(rxdata_r[0:]),
|
||||||
self.rxcharisk_o.eq(rxcharisk_r[0:dw//8])
|
rxcharisk.eq(rxcharisk_r[0:])
|
||||||
]
|
]
|
||||||
for i in range(1, dw//8):
|
for i in range(1, dw//8):
|
||||||
cases[1<<i] = [
|
cases[1<<i] = [
|
||||||
self.rxdata_o.eq(Cat(self.rxdata_i[8*i:dw], rxdata_r[0:8*i])),
|
rxdata.eq(Cat(self.rxdata[8*i:dw], rxdata_r[0:dw+8*i])),
|
||||||
self.rxcharisk_o.eq(Cat(self.rxcharisk_i[i:dw//8], rxcharisk_r[0:i]))
|
rxcharisk.eq(Cat(self.rxcharisk[i:dw//8], rxcharisk_r[0:dw//8+i]))
|
||||||
]
|
]
|
||||||
self.comb += Case(rxcharisk_r, cases)
|
self.comb += Case(rxalignment, cases)
|
||||||
|
|
||||||
class K7SATAPHYRXConvert(Module):
|
|
||||||
def __init__(self):
|
|
||||||
self.rxdata = Signal(16)
|
|
||||||
self.rxcharisk = Signal(2)
|
|
||||||
|
|
||||||
self.source = Source([("data", 32), ("charisk", 4)])
|
|
||||||
###
|
|
||||||
|
|
||||||
# convert data widths
|
|
||||||
rx_converter = RenameClockDomains(Converter([("raw", 16+2)], [("raw", 32+4)]), "sata_rx")
|
|
||||||
self.submodules += rx_converter
|
|
||||||
self.comb += [
|
|
||||||
rx_converter.sink.stb.eq(1),
|
|
||||||
rx_converter.sink.raw.eq(Cat(self.rxdata , self.rxcharisk)),
|
|
||||||
rx_converter.source.ack.eq(1)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# clock domain crossing
|
# clock domain crossing
|
||||||
# SATA device is supposed to lock its tx frequency to its received rx frequency, so this
|
rx_fifo = AsyncFIFO([("data", 32), ("charisk", 4)], 16)
|
||||||
# ensure that sata_rx and sata_tx clock have the same frequency with only not the same
|
|
||||||
# phase and thus ensute the rx_fifo will never be full.
|
|
||||||
rx_fifo = AsyncFIFO([("raw", 36)], 16)
|
|
||||||
self.submodules.rx_fifo = RenameClockDomains(rx_fifo, {"write": "sata_rx", "read": "sys"})
|
self.submodules.rx_fifo = RenameClockDomains(rx_fifo, {"write": "sata_rx", "read": "sys"})
|
||||||
self.comb += [
|
self.comb += [
|
||||||
rx_converter.source.connect(self.rx_fifo.sink),
|
rx_fifo.sink.stb.eq(rxvalid),
|
||||||
self.rx_fifo.source.ack.eq(1),
|
rx_fifo.sink.data.eq(rxdata),
|
||||||
|
rx_fifo.sink.charisk.eq(rxcharisk),
|
||||||
]
|
]
|
||||||
|
|
||||||
# rearrange data
|
# connect source
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.source.stb.eq(self.rx_fifo.source.stb),
|
Record.connect(rx_fifo.source, self.source)
|
||||||
self.source.payload.data.eq(Cat(rx_fifo.source.raw[0:16], rx_fifo.source.raw[18:18+16])),
|
|
||||||
self.source.payload.charisk.eq(Cat(rx_fifo.source.raw[16:18], rx_fifo.source.raw[18+16:18+18])),
|
|
||||||
self.rx_fifo.source.ack.eq(self.source.ack),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class K7SATAPHYTXConvert(Module):
|
class K7SATAPHYTXConvert(Module):
|
||||||
|
|
|
@ -28,6 +28,7 @@ class K7SATAPHYGTX(Module):
|
||||||
|
|
||||||
# Receive Ports
|
# Receive Ports
|
||||||
self.rxuserrdy = Signal()
|
self.rxuserrdy = Signal()
|
||||||
|
self.rxalign = Signal()
|
||||||
|
|
||||||
# Receive Ports - 8b10b Decoder
|
# Receive Ports - 8b10b Decoder
|
||||||
self.rxcharisk = Signal(2)
|
self.rxcharisk = Signal(2)
|
||||||
|
@ -78,7 +79,7 @@ class K7SATAPHYGTX(Module):
|
||||||
|
|
||||||
# Transmit Ports - TX Data Path interface
|
# Transmit Ports - TX Data Path interface
|
||||||
self.gttxreset = Signal()
|
self.gttxreset = Signal()
|
||||||
self.txdata = Signal()
|
self.txdata = Signal(16)
|
||||||
self.txoutclk = Signal()
|
self.txoutclk = Signal()
|
||||||
self.txusrclk = Signal()
|
self.txusrclk = Signal()
|
||||||
self.txusrclk2 = Signal()
|
self.txusrclk2 = Signal()
|
||||||
|
@ -172,6 +173,7 @@ class K7SATAPHYGTX(Module):
|
||||||
rxphalignen = Signal()
|
rxphalignen = Signal()
|
||||||
rxphdlyreset = Signal()
|
rxphdlyreset = Signal()
|
||||||
rxrate = Signal(3)
|
rxrate = Signal(3)
|
||||||
|
rxalign = Signal()
|
||||||
|
|
||||||
self.specials += [
|
self.specials += [
|
||||||
MultiReg(self.rxuserrdy, rxuserrdy, "sata_rx"),
|
MultiReg(self.rxuserrdy, rxuserrdy, "sata_rx"),
|
||||||
|
@ -181,7 +183,8 @@ class K7SATAPHYGTX(Module):
|
||||||
MultiReg(self.rxphalign, rxphalign, "sata_rx"),
|
MultiReg(self.rxphalign, rxphalign, "sata_rx"),
|
||||||
MultiReg(self.rxphalignen, rxphalignen, "sata_rx"),
|
MultiReg(self.rxphalignen, rxphalignen, "sata_rx"),
|
||||||
MultiReg(self.rxphdlyreset, rxphdlyreset, "sata_rx"),
|
MultiReg(self.rxphdlyreset, rxphdlyreset, "sata_rx"),
|
||||||
MultiReg(self.rxrate, rxrate, "sata_rx")
|
MultiReg(self.rxrate, rxrate, "sata_rx"),
|
||||||
|
MultiReg(self.rxalign, rxalign, "sata_rx"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,6 +208,11 @@ class K7SATAPHYGTX(Module):
|
||||||
_PulseSynchronizer(rxcomwakedet, "sata_rx", self.rxcomwakedet, "sys"),
|
_PulseSynchronizer(rxcomwakedet, "sata_rx", self.rxcomwakedet, "sys"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
self.rxbyteisaligned = Signal()
|
||||||
|
self.rxbyterealign = Signal()
|
||||||
|
self.rxcommadet = Signal()
|
||||||
|
|
||||||
# Instance
|
# Instance
|
||||||
gtxe2_channel_parameters = {
|
gtxe2_channel_parameters = {
|
||||||
# Simulation-Only Attributes
|
# Simulation-Only Attributes
|
||||||
|
@ -219,9 +227,9 @@ class K7SATAPHYGTX(Module):
|
||||||
"p_ALIGN_COMMA_ENABLE":ones(10),
|
"p_ALIGN_COMMA_ENABLE":ones(10),
|
||||||
"p_ALIGN_COMMA_WORD":2,
|
"p_ALIGN_COMMA_WORD":2,
|
||||||
"p_ALIGN_MCOMMA_DET":"TRUE",
|
"p_ALIGN_MCOMMA_DET":"TRUE",
|
||||||
"p_ALIGN_MCOMMA_VALUE":K28_5,
|
"p_ALIGN_MCOMMA_VALUE":0b1010000011,
|
||||||
"p_ALIGN_PCOMMA_DET":"TRUE",
|
"p_ALIGN_PCOMMA_DET":"TRUE",
|
||||||
"p_ALIGN_PCOMMA_VALUE":~K28_5,
|
"p_ALIGN_PCOMMA_VALUE":0b0101111100,
|
||||||
"p_SHOW_REALIGN_COMMA":"FALSE",
|
"p_SHOW_REALIGN_COMMA":"FALSE",
|
||||||
"p_RXSLIDE_AUTO_WAIT":7,
|
"p_RXSLIDE_AUTO_WAIT":7,
|
||||||
"p_RXSLIDE_MODE":"OFF",
|
"p_RXSLIDE_MODE":"OFF",
|
||||||
|
@ -616,12 +624,12 @@ class K7SATAPHYGTX(Module):
|
||||||
#o_RXSTATUS=,
|
#o_RXSTATUS=,
|
||||||
|
|
||||||
# Receive Ports - RX Byte and Word Alignment Ports
|
# Receive Ports - RX Byte and Word Alignment Ports
|
||||||
#o_RXBYTEISALIGNED=,
|
o_RXBYTEISALIGNED=self.rxbyteisaligned,
|
||||||
#o_RXBYTEREALIGN=,
|
o_RXBYTEREALIGN=self.rxbyterealign,
|
||||||
#o_RXCOMMADET=,
|
o_RXCOMMADET=self.rxcommadet,
|
||||||
i_RXCOMMADETEN=1,
|
i_RXCOMMADETEN=1,
|
||||||
i_RXMCOMMAALIGNEN=0,
|
i_RXMCOMMAALIGNEN=rxalign,
|
||||||
i_RXPCOMMAALIGNEN=0,
|
i_RXPCOMMAALIGNEN=rxalign,
|
||||||
|
|
||||||
# Receive Ports - RX Channel Bonding Ports
|
# Receive Ports - RX Channel Bonding Ports
|
||||||
#o_RXCHANBONDSEQ=,
|
#o_RXCHANBONDSEQ=,
|
||||||
|
|
|
@ -1,26 +1,8 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
|
|
||||||
K28_5 = 0b1010000011
|
|
||||||
|
|
||||||
ALIGN_VAL = 0x7B4A4ABC
|
ALIGN_VAL = 0x7B4A4ABC
|
||||||
CONT_VAL = 0x9999AA7C
|
|
||||||
DMAT_VAL = 0x3636B57C
|
|
||||||
EOF_VAL = 0xD5D5B57C
|
|
||||||
HOLD_VAL = 0xD5D5AA7C
|
|
||||||
HOLDA_VAL = 0x9595AA7C
|
|
||||||
PMACK_VAL = 0x9595957C
|
|
||||||
PMNAK_VAL = 0xF5F5957C
|
|
||||||
PMREQ_P_VAL = 0x1717B57C
|
|
||||||
PMREQ_S_VAL = 0x7575957C
|
|
||||||
R_ERR_VAL = 0x5656B57C
|
|
||||||
R_IP_VAL = 0x5555B57C
|
|
||||||
R_OK_VAL = 0x3535B57C
|
|
||||||
R_RDY_VAL = 0x4A4A957C
|
|
||||||
SOF_VAL = 0x3737B57C
|
|
||||||
SYNC_VAL = 0xB5B5957C
|
SYNC_VAL = 0xB5B5957C
|
||||||
WTRM_VAL = 0x5858B57C
|
|
||||||
X_RDY_VAL = 0x5757B57C
|
|
||||||
|
|
||||||
def ones(width):
|
def ones(width):
|
||||||
return 2**width-1
|
return 2**width-1
|
||||||
|
|
Loading…
Reference in New Issue