fix alignment (still some transmissions errors --> need to check clocks and resets)

This commit is contained in:
Florent Kermarrec 2014-09-29 13:02:11 +02:00
parent ed752758b0
commit b47153fbfa
5 changed files with 62 additions and 91 deletions

View File

@ -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)
] ]

View File

@ -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,

View File

@ -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):

View File

@ -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=,

View File

@ -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