fix alignment (still some transmissions errors --> need to check clocks and resets)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Sep 2014 11:02:11 +0000 (13:02 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Sep 2014 13:37:35 +0000 (15:37 +0200)
lib/sata/k7sataphy/__init__.py
lib/sata/k7sataphy/ctrl.py
lib/sata/k7sataphy/datapath.py
lib/sata/k7sataphy/gtx.py
lib/sata/k7sataphy/std.py

index f3a3676f30359ca357ccea46309080d1f019f3af..90094e0c5d8858a47d53501a912840cfe2037bba 100644 (file)
@@ -5,7 +5,6 @@ from lib.sata.k7sataphy.std import *
 from lib.sata.k7sataphy.gtx import K7SATAPHYGTX
 from lib.sata.k7sataphy.crg import K7SATAPHYCRG
 from lib.sata.k7sataphy.ctrl import K7SATAPHYHostCtrl, K7SATAPHYDeviceCtrl
-from lib.sata.k7sataphy.datapath import K7SATAPHYRXAlign
 from lib.sata.k7sataphy.datapath import K7SATAPHYRXConvert, K7SATAPHYTXConvert
 
 class K7SATAPHY(Module):
@@ -20,22 +19,18 @@ class K7SATAPHY(Module):
        # CRG / CTRL
                crg = K7SATAPHYCRG(pads, gtx, clk_freq, default_speed)
                if host:
-                       ctrl = K7SATAPHYHostCtrl(gtx, clk_freq)
+                       ctrl = K7SATAPHYHostCtrl(gtx, crg, clk_freq)
                else:
-                       ctrl = K7SATAPHYDeviceCtrl(gtx, clk_freq)
+                       ctrl = K7SATAPHYDeviceCtrl(gtx, crg, clk_freq)
                self.submodules += crg, ctrl
-               self.comb += ctrl.start.eq(crg.ready)
 
        # DATAPATH
-               rxalign = K7SATAPHYRXAlign()
                rxconvert = K7SATAPHYRXConvert()
                txconvert = K7SATAPHYTXConvert()
-               self.submodules += rxalign, rxconvert, txconvert
+               self.submodules += rxconvert, txconvert
                self.comb += [
-                       rxalign.rxdata_i.eq(gtx.rxdata),
-                       rxalign.rxcharisk_i.eq(gtx.rxcharisk),
-                       rxconvert.rxdata.eq(rxalign.rxdata_o),
-                       rxconvert.rxcharisk.eq(rxalign.rxcharisk_o),
+                       rxconvert.rxdata.eq(gtx.rxdata),
+                       rxconvert.rxcharisk.eq(gtx.rxcharisk),
 
                        gtx.txdata.eq(txconvert.txdata),
                        gtx.txcharisk.eq(txconvert.txcharisk)
@@ -53,7 +48,7 @@ class K7SATAPHY(Module):
                                txconvert.sink.charisk.eq(ctrl.txcharisk)
                        ),
                        self.source.stb.eq(rxconvert.source.stb),
-                       self.source.payload.eq(rxconvert.source.payload),
-                       rxconvert.source.ack.eq(self.source.ack),
+                       self.source.payload.eq(rxconvert.source.data),
+                       rxconvert.source.ack.eq(1),
                        ctrl.rxdata.eq(rxconvert.source.data)
                ]
index 7f9648abb191700447adcedd85025f1e26b9da52..07b541bd75558d08babfaf156c80281a75418b96 100644 (file)
@@ -11,8 +11,7 @@ def us(t, clk_freq):
        return ceil(t/clk_period_us)
 
 class K7SATAPHYHostCtrl(Module):
-       def __init__(self, gtx, clk_freq):
-               self.start = Signal()
+       def __init__(self, gtx, crg, clk_freq):
                self.ready = Signal()
 
                self.txdata = Signal(32)
@@ -33,7 +32,7 @@ class K7SATAPHYHostCtrl(Module):
 
                fsm.act("RESET",
                        gtx.txelecidle.eq(1),
-                       If(self.start,
+                       If(crg.ready,
                                NextState("COMINIT")
                        )
                )
@@ -89,8 +88,7 @@ class K7SATAPHYHostCtrl(Module):
                )
                fsm.act("AWAIT_ALIGN",
                        gtx.txelecidle.eq(0),
-                       self.txdata.eq(0x4A4A4A4A), #D10.2
-                       self.txcharisk.eq(0b0000),
+                       gtx.rxalign.eq(1),
                        If(align_detect & ~align_timeout,
                                NextState("SEND_ALIGN")
                        ).Elif(~align_detect & align_timeout,
@@ -143,7 +141,7 @@ class K7SATAPHYHostCtrl(Module):
 
                self.sync += \
                        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)
                                ).Else(
                                        non_align_cnt.eq(0)
@@ -151,8 +149,7 @@ class K7SATAPHYHostCtrl(Module):
                        )
 
 class K7SATAPHYDeviceCtrl(Module):
-       def __init__(self, gtx, clk_freq):
-               self.start = Signal()
+       def __init__(self, gtx, crg, clk_freq):
                self.ready = Signal()
 
                self.txdata = Signal(32)
@@ -172,7 +169,7 @@ class K7SATAPHYDeviceCtrl(Module):
 
                fsm.act("RESET",
                        gtx.txelecidle.eq(1),
-                       If(self.start,
+                       If(crg.ready,
                                NextState("AWAIT_COMINIT")
                        )
                )
@@ -218,6 +215,7 @@ class K7SATAPHYDeviceCtrl(Module):
                )
                fsm.act("SEND_ALIGN",
                        gtx.txelecidle.eq(0),
+                       gtx.rxalign.eq(1),
                        self.txdata.eq(ALIGN_VAL),
                        self.txcharisk.eq(0b0001),
                        If(align_detect,
index 95f115ba0cf05a0e678509255942d936388f7c51..d7e4c73756f9708631a252db7f3549a23fbed456 100644 (file)
@@ -5,69 +5,57 @@ from migen.flow.actor import Sink, Source
 
 from lib.sata.k7sataphy.std import *
 
-class K7SATAPHYRXAlign(Module):
+class K7SATAPHYRXConvert(Module):
        def __init__(self, dw=16):
-               self.rxdata_i = Signal(dw)
-               self.rxcharisk_i = Signal(dw//8)
+               self.rxdata = Signal(dw)
+               self.rxcharisk = Signal(dw//8)
 
-               self.rxdata_o = Signal(dw)
-               self.rxcharisk_o = Signal(dw//8)
+               self.source = Source([("data", 32), ("charisk", 4)])
 
                ###
 
-               rxdata_r = Signal(dw)
-               rxcharisk_r = Signal(dw//8)
+               # byte alignment
+               rxdata_r = Signal(2*dw)
+               rxcharisk_r = Signal((2*dw)//8)
+               rxalignment = Signal(dw//8)
+               rxvalid = Signal()
                self.sync.sata_rx += [
-                       rxdata_r.eq(self.rxdata_i),
-                       rxcharisk_r.eq(self.rxcharisk_i)
+                       rxdata_r.eq(Cat(self.rxdata, rxdata_r[0:dw])),
+                       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[1<<0] = [
-                               self.rxdata_o.eq(rxdata_r[0:dw]),
-                               self.rxcharisk_o.eq(rxcharisk_r[0:dw//8])
+                               rxdata.eq(rxdata_r[0:]),
+                               rxcharisk.eq(rxcharisk_r[0:])
                ]
                for i in range(1, dw//8):
                        cases[1<<i] = [
-                               self.rxdata_o.eq(Cat(self.rxdata_i[8*i:dw], rxdata_r[0:8*i])),
-                               self.rxcharisk_o.eq(Cat(self.rxcharisk_i[i:dw//8], rxcharisk_r[0:i]))
+                               rxdata.eq(Cat(self.rxdata[8*i:dw], rxdata_r[0:dw+8*i])),
+                               rxcharisk.eq(Cat(self.rxcharisk[i:dw//8], rxcharisk_r[0:dw//8+i]))
                        ]
-               self.comb += Case(rxcharisk_r, 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)
-               ]
-
+               self.comb += Case(rxalignment, cases)
 
                # clock domain crossing
-               # SATA device is supposed to lock its tx frequency to its received rx frequency, so this
-               # 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)
+               rx_fifo = AsyncFIFO([("data", 32), ("charisk", 4)], 16)
                self.submodules.rx_fifo = RenameClockDomains(rx_fifo, {"write": "sata_rx", "read": "sys"})
                self.comb += [
-                       rx_converter.source.connect(self.rx_fifo.sink),
-                       self.rx_fifo.source.ack.eq(1),
+                       rx_fifo.sink.stb.eq(rxvalid),
+                       rx_fifo.sink.data.eq(rxdata),
+                       rx_fifo.sink.charisk.eq(rxcharisk),
                ]
 
-               # rearrange data
+               # connect source
                self.comb += [
-                       self.source.stb.eq(self.rx_fifo.source.stb),
-                       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),
+                       Record.connect(rx_fifo.source, self.source)
                ]
 
 class K7SATAPHYTXConvert(Module):
index d7a3632c25e1ad1b01023ff1d92d8c8615580d3d..f307139233af61fc357d805d1620188f33d15b1f 100644 (file)
@@ -28,6 +28,7 @@ class K7SATAPHYGTX(Module):
 
                # Receive Ports
                self.rxuserrdy = Signal()
+               self.rxalign = Signal()
 
                # Receive Ports - 8b10b Decoder
                self.rxcharisk = Signal(2)
@@ -78,7 +79,7 @@ class K7SATAPHYGTX(Module):
 
                # Transmit Ports - TX Data Path interface
                self.gttxreset = Signal()
-               self.txdata = Signal()
+               self.txdata = Signal(16)
                self.txoutclk = Signal()
                self.txusrclk = Signal()
                self.txusrclk2 = Signal()
@@ -172,6 +173,7 @@ class K7SATAPHYGTX(Module):
                rxphalignen = Signal()
                rxphdlyreset = Signal()
                rxrate = Signal(3)
+               rxalign = Signal()
 
                self.specials += [
                        MultiReg(self.rxuserrdy, rxuserrdy, "sata_rx"),
@@ -181,7 +183,8 @@ class K7SATAPHYGTX(Module):
                        MultiReg(self.rxphalign, rxphalign, "sata_rx"),
                        MultiReg(self.rxphalignen, rxphalignen, "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"),
                ]       
 
+
+               self.rxbyteisaligned = Signal()
+               self.rxbyterealign = Signal()
+               self.rxcommadet = Signal()
+
        # Instance
                gtxe2_channel_parameters = {
                                # Simulation-Only Attributes
@@ -219,9 +227,9 @@ class K7SATAPHYGTX(Module):
                                        "p_ALIGN_COMMA_ENABLE":ones(10),
                                        "p_ALIGN_COMMA_WORD":2,
                                        "p_ALIGN_MCOMMA_DET":"TRUE",
-                                       "p_ALIGN_MCOMMA_VALUE":K28_5,
+                                       "p_ALIGN_MCOMMA_VALUE":0b1010000011,
                                        "p_ALIGN_PCOMMA_DET":"TRUE",
-                                       "p_ALIGN_PCOMMA_VALUE":~K28_5,
+                                       "p_ALIGN_PCOMMA_VALUE":0b0101111100,
                                        "p_SHOW_REALIGN_COMMA":"FALSE",
                                        "p_RXSLIDE_AUTO_WAIT":7,
                                        "p_RXSLIDE_MODE":"OFF",
@@ -616,12 +624,12 @@ class K7SATAPHYGTX(Module):
                                        #o_RXSTATUS=,
 
                                # Receive Ports - RX Byte and Word Alignment Ports
-                                       #o_RXBYTEISALIGNED=,
-                                       #o_RXBYTEREALIGN=,
-                                       #o_RXCOMMADET=,
+                                       o_RXBYTEISALIGNED=self.rxbyteisaligned,
+                                       o_RXBYTEREALIGN=self.rxbyterealign,
+                                       o_RXCOMMADET=self.rxcommadet,
                                        i_RXCOMMADETEN=1,
-                                       i_RXMCOMMAALIGNEN=0,
-                                       i_RXPCOMMAALIGNEN=0,
+                                       i_RXMCOMMAALIGNEN=rxalign,
+                                       i_RXPCOMMAALIGNEN=rxalign,
 
                                # Receive Ports - RX Channel Bonding Ports
                                        #o_RXCHANBONDSEQ=,
index c5b56e63f504da35657e63be72b5ada5e1f98fe3..8417a11830e6577106961ad12ee9308cba0c990d 100644 (file)
@@ -1,26 +1,8 @@
 from migen.fhdl.std import *
 from migen.genlib.record import *
 
-K28_5 = 0b1010000011
-
 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
-WTRM_VAL    = 0x5858B57C
-X_RDY_VAL   = 0x5757B57C
 
 def ones(width):
        return 2**width-1