simplify and clean up
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Sep 2014 16:25:24 +0000 (18:25 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Sep 2014 22:50:03 +0000 (00:50 +0200)
lib/sata/k7sataphy/__init__.py
lib/sata/k7sataphy/crg.py
lib/sata/k7sataphy/ctrl.py
lib/sata/k7sataphy/datapath.py
lib/sata/k7sataphy/gtx.py

index 90094e0c5d8858a47d53501a912840cfe2037bba..ba4ef1b4719a31b282727668f9630bb420d96162 100644 (file)
@@ -1,54 +1,23 @@
 from migen.fhdl.std import *
-from migen.flow.actor import Sink, Source
 
 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 K7SATAPHYRXConvert, K7SATAPHYTXConvert
+from lib.sata.k7sataphy.datapath import K7SATAPHYDatapath
 
 class K7SATAPHY(Module):
-       def __init__(self, pads, clk_freq, host=True, default_speed="SATA3"):
-               self.sink = Sink([("d", 32)])
-               self.source = Source([("d", 32)])
-
+       def __init__(self, pads, clk_freq, host=True, default_speed="SATA1"):
        # GTX
-               gtx = K7SATAPHYGTX(pads, default_speed)
-               self.submodules += gtx
+               self.submodules.gtx = K7SATAPHYGTX(pads, default_speed)
 
        # CRG / CTRL
-               crg = K7SATAPHYCRG(pads, gtx, clk_freq, default_speed)
+               self.submodules.crg = K7SATAPHYCRG(pads, self.gtx, clk_freq, default_speed)
                if host:
-                       ctrl = K7SATAPHYHostCtrl(gtx, crg, clk_freq)
+                       self.submodules.ctrl = K7SATAPHYHostCtrl(self.gtx, self.crg, clk_freq)
                else:
-                       ctrl = K7SATAPHYDeviceCtrl(gtx, crg, clk_freq)
-               self.submodules += crg, ctrl
+                       self.submodules.ctrl = K7SATAPHYDeviceCtrl(self.gtx, self.crg, clk_freq)
 
        # DATAPATH
-               rxconvert = K7SATAPHYRXConvert()
-               txconvert = K7SATAPHYTXConvert()
-               self.submodules += rxconvert, txconvert
-               self.comb += [
-                       rxconvert.rxdata.eq(gtx.rxdata),
-                       rxconvert.rxcharisk.eq(gtx.rxcharisk),
-
-                       gtx.txdata.eq(txconvert.txdata),
-                       gtx.txcharisk.eq(txconvert.txcharisk)
-               ]
-
-               self.comb += [
-                       If(ctrl.ready,
-                               txconvert.sink.stb.eq(self.sink.stb),
-                               txconvert.sink.data.eq(self.sink.d),
-                               txconvert.sink.charisk.eq(0),
-                               self.sink.ack.eq(txconvert.sink.ack),
-                       ).Else(
-                               txconvert.sink.stb.eq(1),
-                               txconvert.sink.data.eq(ctrl.txdata),
-                               txconvert.sink.charisk.eq(ctrl.txcharisk)
-                       ),
-                       self.source.stb.eq(rxconvert.source.stb),
-                       self.source.payload.eq(rxconvert.source.data),
-                       rxconvert.source.ack.eq(1),
-                       ctrl.rxdata.eq(rxconvert.source.data)
-               ]
+               self.submodules.datapath = K7SATAPHYDatapath(self.gtx, self.ctrl)
+               self.sink, self.source = self.datapath.sink, self.datapath.source
index 3b9a911c0bf9e1e02bab066741127fb1ea7a4bff..1bbec2cbf5cf36e787d957b0a5e496cfd4a7d021 100644 (file)
@@ -9,11 +9,8 @@ from lib.sata.k7sataphy.std import *
 class K7SATAPHYReconfig(Module):
        def __init__(self, channel_drp, mmcm_drp):
                self.speed = Signal(3)
+
                ###
-               speed_r = Signal(3)
-               speed_change = Signal()
-               self.sync += speed_r.eq(self.speed)
-               self.comb += speed_change.eq(self.speed != speed_r)
 
                drp_sel = Signal()
                drp = DRPBus()
@@ -23,6 +20,7 @@ class K7SATAPHYReconfig(Module):
                        ).Else(
                                drp.connect(channel_drp)
                        )
+               # Todo
 
 class K7SATAPHYCRG(Module):
        def __init__(self, pads, gtx, clk_freq, default_speed):
@@ -34,7 +32,7 @@ class K7SATAPHYCRG(Module):
 
        # CPLL
                # (SATA3) 150MHz / VCO @ 3GHz / Line rate @ 6Gbps
-               # (SATA2 & SATA1) VCO still @ 3 GHz, Line rate is decreased with output divivers.
+               # (SATA2 & SATA1) VCO still @ 3 GHz, Line rate is decreased with output dividers.
                # When changing rate, reconfiguration of the CPLL over DRP is needed to:
                #  - update the output divider
                #  - update the equalizer configuration (specific for each line rate).
@@ -93,9 +91,9 @@ class K7SATAPHYCRG(Module):
                ]
 
        # RX clocking
-               # (SATA3) sata_rx recovered clk @ 300MHz from CPLL RXOUTCLK
-               # (SATA2) sata_rx recovered clk @ 150MHz from CPLL RXOUTCLK
-               # (SATA1) sata_rx recovered clk @ 150MHz from CPLL RXOUTCLK             
+               # (SATA3) sata_rx recovered clk @ 300MHz from GTX RXOUTCLK
+               # (SATA2) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK
+               # (SATA1) sata_rx recovered clk @ 150MHz from GTX RXOUTCLK              
                self.specials += [
                        Instance("BUFG", i_I=gtx.rxoutclk, o_O=self.cd_sata_rx.clk),
                ]
@@ -104,25 +102,8 @@ class K7SATAPHYCRG(Module):
                        gtx.rxusrclk2.eq(self.cd_sata_rx.clk)
                ]
 
-       # Bypass TX buffer
-               self.comb += [
-                       gtx.txphdlyreset.eq(0),
-                       gtx.txphalignen.eq(0),
-                       gtx.txdlyen.eq(0),
-                       gtx.txphalign.eq(0),
-                       gtx.txphinit.eq(0)
-               ]
-
-       # Bypass RX buffer
-               self.comb += [
-                       gtx.rxphdlyreset.eq(0),
-                       gtx.rxdlyen.eq(0),
-                       gtx.rxphalign.eq(0),
-                       gtx.rxphalignen.eq(0),
-               ]
-
        # Configuration Reset
-               # After configuration, GTX resets have to stay low for at least 500ns
+               # After configuration, GTX's resets have to stay low for at least 500ns
                # See AR43482
                reset_en = Signal()
                clk_period_ns = 1000000000/clk_freq
@@ -227,6 +208,7 @@ class K7SATAPHYCRG(Module):
                        )
                )
 
+       # Ready
                self.comb += self.ready.eq(tx_reset_fsm.ongoing("READY") & rx_reset_fsm.ongoing("READY"))
 
        # Reset PLL
index 983980a15d8601943a63889bf01a3cf8c644e40c..8c2d1ebac5562565b7b73e6318366155c629b1e0 100644 (file)
@@ -19,9 +19,13 @@ class K7SATAPHYHostCtrl(Module):
 
                self.rxdata = Signal(32)
 
-               align_timeout = Signal()
                align_detect = Signal()
-               retry_cnt = Signal(32)
+               align_timeout_cnt = Signal(32)
+               align_timeout = Signal()
+
+               retry_timeout_cnt = Signal(32)
+               retry_timeout = Signal()
+
                non_align_cnt = Signal(4)
 
                txcominit = Signal()
@@ -48,7 +52,7 @@ class K7SATAPHYHostCtrl(Module):
                        If(gtx.rxcominitdet,
                                NextState("AWAIT_NO_COMINIT")
                        ).Else(
-                               If(retry_cnt == 0,
+                               If(retry_timeout,
                                        NextState("RESET")
                                )
                        )
@@ -75,7 +79,7 @@ class K7SATAPHYHostCtrl(Module):
                        If(gtx.rxcomwakedet,
                                NextState("AWAIT_NO_COMWAKE")
                        ).Else(
-                               If(retry_cnt == 0,
+                               If(retry_timeout,
                                        NextState("RESET")
                                )
                        )
@@ -93,6 +97,8 @@ 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")
@@ -104,7 +110,7 @@ class K7SATAPHYHostCtrl(Module):
                        gtx.txelecidle.eq(0),
                        self.txdata.eq(ALIGN_VAL),
                        self.txcharisk.eq(0b0001),
-                       If(non_align_cnt == 15,
+                       If(non_align_cnt == 3,
                                NextState("READY")
                        )
                )
@@ -124,9 +130,8 @@ class K7SATAPHYHostCtrl(Module):
                        gtx.txcominit.eq(txcominit & ~txcominit_d),
                        gtx.txcomwake.eq(txcomwake & ~txcomwake_d),
                ]
-               self.comb +=  align_detect.eq(self.rxdata == ALIGN_VAL);
 
-               align_timeout_cnt = Signal(16)
+               self.comb +=  align_detect.eq(self.rxdata == ALIGN_VAL);        
                self.sync += \
                        If(fsm.ongoing("RESET"),
                                align_timeout_cnt.eq(us(873, clk_freq))
@@ -137,10 +142,11 @@ class K7SATAPHYHostCtrl(Module):
 
                self.sync += \
                        If(fsm.ongoing("RESET") | fsm.ongoing("AWAIT_NO_COMINIT"),
-                               retry_cnt.eq(us(10000, clk_freq))
+                               retry_timeout_cnt.eq(us(10000, clk_freq))
                        ).Elif(fsm.ongoing("AWAIT_COMINIT") | fsm.ongoing("AWAIT_COMWAKE"),
-                               retry_cnt.eq(retry_cnt-1)
+                               retry_timeout_cnt.eq(retry_timeout_cnt-1)
                        )
+               self.comb += retry_timeout.eq(retry_timeout_cnt == 0)
 
                self.sync += \
                        If(fsm.ongoing("SEND_ALIGN"),
@@ -160,9 +166,12 @@ class K7SATAPHYDeviceCtrl(Module):
 
                self.rxdata = Signal(32)
 
-               align_timeout = Signal()
                align_detect = Signal()
-               retry_cnt = Signal(32)
+               align_timeout = Signal()
+               align_timeout_cnt = Signal(32)
+
+               retry_timeout_cnt = Signal(32)
+               retry_timeout = Signal()
 
                txcominit = Signal()
                txcomwake = Signal()
@@ -194,7 +203,7 @@ class K7SATAPHYDeviceCtrl(Module):
                        If(gtx.rxcomwakedet,
                                NextState("AWAIT_NO_COMWAKE")
                        ).Else(
-                               If(retry_cnt == 0,
+                               If(retry_timeout,
                                        NextState("RESET")
                                )
                        )
@@ -253,9 +262,8 @@ class K7SATAPHYDeviceCtrl(Module):
                        gtx.txcominit.eq(txcominit & ~txcominit_d),
                        gtx.txcomwake.eq(txcomwake & ~txcomwake),
                ]
-               self.comb +=  align_detect.eq(self.rxdata == ALIGN_VAL);
 
-               align_timeout_cnt = Signal(16)
+               self.comb +=  align_detect.eq(self.rxdata == ALIGN_VAL);
                self.sync += \
                        If(fsm.ongoing("RESET"),
                                align_timeout_cnt.eq(us(55, clk_freq))
@@ -266,7 +274,8 @@ class K7SATAPHYDeviceCtrl(Module):
 
                self.sync += \
                        If(fsm.ongoing("RESET"),
-                               retry_cnt.eq(us(10000, clk_freq))
+                               retry_timeout_cnt.eq(us(10000, clk_freq))
                        ).Elif(fsm.ongoing("AWAIT_COMWAKE"),
-                               retry_cnt.eq(retry_cnt-1)
+                               retry_timeout_cnt.eq(retry_timeout_cnt-1)
                        )
+               self.comb += retry_timeout.eq(retry_timeout_cnt == 0)
index d7e4c73756f9708631a252db7f3549a23fbed456..2a607b37d7b5c1ed07c0d467d52a64a1af33d760 100644 (file)
 from migen.fhdl.std import *
+from migen.genlib.misc import chooser
 from migen.actorlib.fifo import AsyncFIFO
-from migen.actorlib.structuring import Converter
 from migen.flow.actor import Sink, Source
 
 from lib.sata.k7sataphy.std import *
 
-class K7SATAPHYRXConvert(Module):
-       def __init__(self, dw=16):
-               self.rxdata = Signal(dw)
-               self.rxcharisk = Signal(dw//8)
-
+class K7SATAPHYDatapathRX(Module):
+       def __init__(self):
+               self.sink = Sink([("data", 16), ("charisk", 2)])
                self.source = Source([("data", 32), ("charisk", 4)])
 
                ###
 
-               # byte alignment
-               rxdata_r = Signal(2*dw)
-               rxcharisk_r = Signal((2*dw)//8)
-               rxalignment = Signal(dw//8)
-               rxvalid = Signal()
+       # bytes alignment
+               
+               # shift register
+               data_sr = Signal(32+8)
+               charisk_sr = Signal(4+1)
+               data_sr_d = Signal(32+8)
+               charisk_sr_d = Signal(4+1)
+               self.comb += [
+                       data_sr.eq(Cat(self.sink.data, data_sr_d)),
+                       charisk_sr.eq(Cat(self.sink.charisk, charisk_sr_d))
+               ]
                self.sync.sata_rx += [
-                       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)
+                       data_sr_d.eq(data_sr),
+                       charisk_sr_d.eq(charisk_sr)
+               ]
+
+               # alignment
+               alignment = Signal()
+               valid = Signal()
+               self.sync.sata_rx += [
+                       If(self.sink.charisk !=0,
+                               alignment.eq(self.sink.charisk[1]),
+                               valid.eq(0)
                        ).Else(
-                               rxvalid.eq(~rxvalid)
+                               valid.eq(~valid)
                        )
                ]
 
-               rxdata = Signal(2*dw)
-               rxcharisk = Signal((2*dw)//8)
-               cases = {}
-               cases[1<<0] = [
-                               rxdata.eq(rxdata_r[0:]),
-                               rxcharisk.eq(rxcharisk_r[0:])
-               ]
-               for i in range(1, dw//8):
-                       cases[1<<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(rxalignment, cases)
-
-               # clock domain crossing
-               rx_fifo = AsyncFIFO([("data", 32), ("charisk", 4)], 16)
-               self.submodules.rx_fifo = RenameClockDomains(rx_fifo, {"write": "sata_rx", "read": "sys"})
+               # 16 to 32
+               data = Signal(32)
+               charisk = Signal(4)
                self.comb += [
-                       rx_fifo.sink.stb.eq(rxvalid),
-                       rx_fifo.sink.data.eq(rxdata),
-                       rx_fifo.sink.charisk.eq(rxcharisk),
+                       If(~alignment,
+                               data.eq(data_sr[0:32]),
+                               charisk.eq(charisk_sr[0:4])
+                       ).Else(
+                               data.eq(data_sr[8:40]),
+                               charisk.eq(charisk_sr[1:5])
+                       )
                ]
 
-               # connect source
+       # clock domain crossing
+               # (SATA3) 300MHz sata_rx clk to sys_clk
+               # (SATA2) 150MHz sata_rx clk to sys_clk
+               # (SATA1) 75MHz sata_rx clk to sys_clk
+               # requirements:
+               # due to the convertion ratio of 2, sys_clk need to be > sata_rx/2
+               # source destination is always able to accept data (ack always 1)
+               fifo = AsyncFIFO([("data", 32), ("charisk", 4)], 16)
+               self.submodules.fifo = RenameClockDomains(fifo, {"write": "sata_rx", "read": "sys"})
                self.comb += [
-                       Record.connect(rx_fifo.source, self.source)
+                       fifo.sink.stb.eq(valid),
+                       fifo.sink.data.eq(data),
+                       fifo.sink.charisk.eq(charisk),
                ]
+               self.comb += Record.connect(fifo.source, self.source)
 
-class K7SATAPHYTXConvert(Module):
+class K7SATAPHYDatapathTX(Module):
        def __init__(self):
                self.sink = Sink([("data", 32), ("charisk", 4)])
+               self.source = Source([("data", 16), ("charisk", 2)])
 
-               self.txdata = Signal(16)
-               self.txcharisk = Signal(2)
                ###
 
-               # convert data widths
-               tx_converter = RenameClockDomains(Converter([("raw", 32+4)], [("raw", 16+2)]), "sata_tx")
-               self.submodules += tx_converter
+       # clock domain crossing
+               # (SATA3) sys_clk to 300MHz sata_tx clk
+               # (SATA2) sys_clk to 150MHz sata_tx clk
+               # (SATA1) sys_clk to 75MHz sata_tx clk
+               # requirements:
+               # source destination is always able to accept data (ack always 1)
+               fifo = AsyncFIFO([("data", 32), ("charisk", 4)], 16)
+               self.submodules.fifo = RenameClockDomains(fifo, {"write": "sys", "read": "sata_tx"})
+               self.comb += Record.connect(self.sink, fifo.sink)
+
+               # 32 to 16
+               mux = Signal()
+               last = Signal()
                self.comb += [
-                       Cat(self.txdata, self.txcharisk).eq(tx_converter.source.raw),
-                       tx_converter.source.ack.eq(1),
+                       last.eq(mux == 1),
+                       self.source.stb.eq(fifo.source.stb),
+                       fifo.source.ack.eq(last),
                ]
+               self.sync.sata_tx += [
+                       If(self.source.stb,
+                               If(last,
+                                       mux.eq(0)
+                               ).Else(
+                                       mux.eq(mux + 1)
+                               )
+                       )
+               ]
+               self.comb += [
+                       chooser(fifo.source.data, mux, self.source.data),
+                       chooser(fifo.source.charisk, mux, self.source.charisk)
+               ]
+
+class K7SATAPHYDatapath(Module):
+       def __init__(self, gtx, ctrl):
+               self.sink = Sink([("d", 32)])
+               self.source = Source([("d", 32)])
 
-               # clock domain crossing
-               tx_fifo = AsyncFIFO([("raw", 36)], 16)
-               self.submodules.tx_fifo = RenameClockDomains(tx_fifo, {"write": "sys", "read": "sata_tx"})
+               ###
+
+       # change data width & cross domain crossing
+               rx = K7SATAPHYDatapathRX()
+               tx = K7SATAPHYDatapathTX()
+               self.submodules += rx, tx
                self.comb += [
-                       tx_fifo.source.connect(tx_converter.sink),
-                       self.tx_fifo.sink.stb.eq(1),
+                       rx.sink.data.eq(gtx.rxdata),
+                       rx.sink.charisk.eq(gtx.rxcharisk),
+
+                       gtx.txdata.eq(tx.source.data),
+                       gtx.txcharisk.eq(tx.source.charisk),
                ]
 
-               # rearrange data
+       # user / ctrl mux
                self.comb += [
-                       self.tx_fifo.sink.stb.eq(self.sink.stb),
-                       self.tx_fifo.sink.raw.eq(Cat(self.sink.data[0:16],  self.sink.charisk[0:2],
-                                                                                self.sink.data[16:32], self.sink.charisk[2:4])),
-                       self.sink.ack.eq(self.tx_fifo.sink.ack),
+                       # user
+                       If(ctrl.ready,
+                               tx.sink.stb.eq(self.sink.stb),
+                               tx.sink.data.eq(self.sink.d),
+                               tx.sink.charisk.eq(0),
+                               self.sink.ack.eq(tx.sink.ack),
+
+                               self.source.stb.eq(rx.source.stb),
+                               self.source.d.eq(rx.source.data),
+                               rx.source.ack.eq(1),
+                       # ctrl
+                       ).Else(
+                               tx.sink.stb.eq(1),
+                               tx.sink.data.eq(ctrl.txdata),
+                               tx.sink.charisk.eq(ctrl.txcharisk),
+
+                               ctrl.rxdata.eq(rx.source.data),
+                               rx.source.ack.eq(1),
+                       )                       
                ]
index b2eed8d287e69131bd7a6cf8ca76d33c5cd4bf00..2ba6f7c59651b534fea875e7ebda4e0faf9a8aef 100644 (file)
@@ -1,8 +1,5 @@
 from migen.fhdl.std import *
 from migen.genlib.cdc import *
-from migen.actorlib.fifo import AsyncFIFO
-from migen.actorlib.structuring import Converter
-from migen.flow.actor import Sink, Source
 
 from lib.sata.k7sataphy.std import *
 
@@ -213,6 +210,23 @@ class K7SATAPHYGTX(Module):
                self.rxbyterealign = Signal()
                self.rxcommadet = Signal()
 
+       # Bypass TX buffer
+               self.comb += [
+                       self.txphdlyreset.eq(0),
+                       self.txphalignen.eq(0),
+                       self.txdlyen.eq(0),
+                       self.txphalign.eq(0),
+                       self.txphinit.eq(0)
+               ]
+
+       # Bypass RX buffer
+               self.comb += [
+                       self.rxphdlyreset.eq(0),
+                       self.rxdlyen.eq(0),
+                       self.rxphalign.eq(0),
+                       self.rxphalignen.eq(0),
+               ]
+
        # Instance
                gtxe2_channel_parameters = {
                                # Simulation-Only Attributes