reorganize code
- use sys_clk of 166.66MHz and using it instead of sata clk. - rename clocking to CRG since it also handles resets. - create datapath and move code from gtx.
This commit is contained in:
parent
879478a6e4
commit
c27f24c4c0
|
@ -2,10 +2,11 @@ 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, K7SATAPHYRXAlign
|
||||
from lib.sata.k7sataphy.gtx import K7SATAPHYRXConvert, K7SATAPHYTXConvert
|
||||
from lib.sata.k7sataphy.clocking import K7SATAPHYClocking
|
||||
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):
|
||||
def __init__(self, pads, clk_freq, host=True,):
|
||||
|
@ -17,7 +18,7 @@ class K7SATAPHY(Module):
|
|||
gtx.rxrate.eq(0b000),
|
||||
gtx.txrate.eq(0b000),
|
||||
]
|
||||
clocking = K7SATAPHYClocking(pads, gtx, clk_freq)
|
||||
clocking = K7SATAPHYCRG(pads, gtx, clk_freq)
|
||||
rxalign = K7SATAPHYRXAlign()
|
||||
rxconvert = K7SATAPHYRXConvert()
|
||||
txconvert = K7SATAPHYTXConvert()
|
||||
|
|
|
@ -24,11 +24,10 @@ class K7SATAPHYReconfig(Module):
|
|||
drp.connect(channel_drp)
|
||||
)
|
||||
|
||||
class K7SATAPHYClocking(Module):
|
||||
class K7SATAPHYCRG(Module):
|
||||
def __init__(self, pads, gtx, clk_freq):
|
||||
self.reset = Signal()
|
||||
|
||||
self.clock_domains.cd_sata = ClockDomain()
|
||||
self.clock_domains.cd_sata_tx = ClockDomain()
|
||||
self.clock_domains.cd_sata_rx = ClockDomain()
|
||||
|
||||
|
@ -118,7 +117,7 @@ class K7SATAPHYClocking(Module):
|
|||
|
||||
|
||||
# Configuration Reset
|
||||
# After configuration, GTX resets can not be asserted for 500ns
|
||||
# After configuration, GTX resets have to stay low for at least 500ns
|
||||
# See AR43482
|
||||
reset_en = Signal()
|
||||
clk_period_ns = 1000000000/clk_freq
|
|
@ -119,7 +119,7 @@ class K7SATAPHYHostCtrl(Module):
|
|||
|
||||
txcominit_d = Signal()
|
||||
txcomwake_d = Signal()
|
||||
self.sync.sata += [
|
||||
self.sync += [
|
||||
txcominit_d.eq(txcominit),
|
||||
txcomwake_d.eq(txcomwake),
|
||||
gtx.txcominit.eq(txcominit & ~txcominit_d),
|
||||
|
@ -128,7 +128,7 @@ class K7SATAPHYHostCtrl(Module):
|
|||
self.comb += align_detect.eq(self.rxdata == ALIGN_VAL);
|
||||
|
||||
align_timeout_cnt = Signal(16)
|
||||
self.sync.sata += \
|
||||
self.sync += \
|
||||
If(fsm.ongoing("RESET"),
|
||||
If(self.speed == 0b100,
|
||||
align_timeout_cnt.eq(us(873, "SATA3"))
|
||||
|
@ -142,7 +142,7 @@ class K7SATAPHYHostCtrl(Module):
|
|||
)
|
||||
self.comb += align_timeout.eq(align_timeout_cnt == 0)
|
||||
|
||||
self.sync.sata += \
|
||||
self.sync += \
|
||||
If(fsm.ongoing("RESET") | fsm.ongoing("AWAIT_NO_COMINIT"),
|
||||
If(self.speed == 0b100,
|
||||
retry_cnt.eq(us(10000, "SATA3"))
|
||||
|
@ -155,7 +155,7 @@ class K7SATAPHYHostCtrl(Module):
|
|||
retry_cnt.eq(retry_cnt-1)
|
||||
)
|
||||
|
||||
self.sync.sata += \
|
||||
self.sync += \
|
||||
If(fsm.ongoing("SEND_ALIGN"),
|
||||
If(self.rxdata[0:8] == K28_5,
|
||||
non_align_cnt.eq(non_align_cnt + 1)
|
||||
|
@ -250,7 +250,7 @@ class K7SATAPHYDeviceCtrl(Module):
|
|||
|
||||
txcominit_d = Signal()
|
||||
txcomwake_d = Signal()
|
||||
self.sync.sata += [
|
||||
self.sync += [
|
||||
txcominit_d.eq(txcominit),
|
||||
txcomwake_d.eq(txcomwake),
|
||||
gtx.txcominit.eq(txcominit & ~txcominit_d),
|
||||
|
@ -259,7 +259,7 @@ class K7SATAPHYDeviceCtrl(Module):
|
|||
self.comb += align_detect.eq(self.rxdata == ALIGN_VAL);
|
||||
|
||||
align_timeout_cnt = Signal(16)
|
||||
self.sync.sata += \
|
||||
self.sync += \
|
||||
If(fsm.ongoing("RESET"),
|
||||
If(self.speed == 0b100,
|
||||
align_timeout_cnt.eq(us(55, "SATA3"))
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
from migen.fhdl.std 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 *
|
||||
|
||||
class K7SATAPHYRXAlign(Module):
|
||||
def __init__(self, dw=16):
|
||||
self.rxdata_i = Signal(dw)
|
||||
self.rxcharisk_i = Signal(dw//8)
|
||||
|
||||
self.rxdata_o = Signal(dw)
|
||||
self.rxcharisk_o = Signal(dw//8)
|
||||
|
||||
###
|
||||
|
||||
rxdata_r = Signal(dw)
|
||||
rxcharisk_r = Signal(dw//8)
|
||||
self.sync.sata_rx += [
|
||||
rxdata_r.eq(self.rxdata_i),
|
||||
rxcharisk_r.eq(self.rxcharisk_i)
|
||||
]
|
||||
cases = {}
|
||||
cases[1<<0] = [
|
||||
self.rxdata_o.eq(rxdata_r[0:dw]),
|
||||
self.rxcharisk_o.eq(rxcharisk_r[0:dw//8])
|
||||
]
|
||||
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]))
|
||||
]
|
||||
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)
|
||||
]
|
||||
|
||||
|
||||
# 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)
|
||||
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),
|
||||
]
|
||||
|
||||
# rearrange data
|
||||
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),
|
||||
]
|
||||
|
||||
class K7SATAPHYTXConvert(Module):
|
||||
def __init__(self):
|
||||
self.sink = Sink([("data", 32), ("charisk", 4)])
|
||||
|
||||
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
|
||||
self.comb += [
|
||||
Cat(self.txdata, self.txcharisk).eq(tx_converter.source.raw),
|
||||
tx_converter.source.ack.eq(1),
|
||||
]
|
||||
|
||||
# clock domain crossing
|
||||
tx_fifo = AsyncFIFO([("raw", 36)], 16)
|
||||
self.submodules.tx_fifo = RenameClockDomains(tx_fifo, {"write": "sys", "read": "sata_tx"})
|
||||
self.comb += [
|
||||
tx_fifo.source.connect(tx_converter.sink),
|
||||
self.tx_fifo.sink.stb.eq(1),
|
||||
]
|
||||
|
||||
# rearrange data
|
||||
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),
|
||||
]
|
|
@ -759,100 +759,3 @@ class K7SATAPHYGTX(Module):
|
|||
|
||||
**gtxe2_channel_parameters
|
||||
)
|
||||
|
||||
class K7SATAPHYRXAlign(Module):
|
||||
def __init__(self, dw=16):
|
||||
self.rxdata_i = Signal(dw)
|
||||
self.rxcharisk_i = Signal(dw//8)
|
||||
|
||||
self.rxdata_o = Signal(dw)
|
||||
self.rxcharisk_o = Signal(dw//8)
|
||||
|
||||
###
|
||||
|
||||
rxdata_r = Signal(dw)
|
||||
rxcharisk_r = Signal(dw//8)
|
||||
self.sync.sata_rx += [
|
||||
rxdata_r.eq(self.rxdata_i),
|
||||
rxcharisk_r.eq(self.rxcharisk_i)
|
||||
]
|
||||
cases = {}
|
||||
cases[1<<0] = [
|
||||
self.rxdata_o.eq(rxdata_r[0:dw]),
|
||||
self.rxcharisk_o.eq(rxcharisk_r[0:dw//8])
|
||||
]
|
||||
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]))
|
||||
]
|
||||
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)
|
||||
]
|
||||
|
||||
|
||||
# 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)
|
||||
self.submodules.rx_fifo = RenameClockDomains(rx_fifo, {"write": "sata_rx", "read": "sata"})
|
||||
self.comb += [
|
||||
rx_converter.source.connect(self.rx_fifo.sink),
|
||||
self.rx_fifo.source.ack.eq(1),
|
||||
]
|
||||
|
||||
# rearrange data
|
||||
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),
|
||||
]
|
||||
|
||||
class K7SATAPHYTXConvert(Module):
|
||||
def __init__(self):
|
||||
self.sink = Sink([("data", 32), ("charisk", 4)])
|
||||
|
||||
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
|
||||
self.comb += [
|
||||
Cat(self.txdata, self.txcharisk).eq(tx_converter.source.raw),
|
||||
tx_converter.source.ack.eq(1),
|
||||
]
|
||||
|
||||
# clock domain crossing
|
||||
tx_fifo = AsyncFIFO([("raw", 36)], 16)
|
||||
self.submodules.tx_fifo = RenameClockDomains(tx_fifo, {"write": "sata", "read": "sata_tx"})
|
||||
self.comb += [
|
||||
tx_fifo.source.connect(tx_converter.sink),
|
||||
self.tx_fifo.sink.stb.eq(1),
|
||||
]
|
||||
|
||||
# rearrange data
|
||||
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),
|
||||
]
|
||||
|
|
|
@ -30,8 +30,8 @@ class _CRG(Module):
|
|||
p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1,
|
||||
i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
|
||||
|
||||
# 125MHz
|
||||
p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys,
|
||||
# 166.66MHz
|
||||
p_CLKOUT0_DIVIDE=6, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys,
|
||||
|
||||
p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, #o_CLKOUT1=,
|
||||
|
||||
|
@ -90,7 +90,7 @@ class TestDesign(UART2WB):
|
|||
default_platform = "kc705"
|
||||
|
||||
def __init__(self, platform):
|
||||
clk_freq = 125*1000000
|
||||
clk_freq = 166666*1000
|
||||
UART2WB.__init__(self, platform, clk_freq)
|
||||
self.submodules.crg = _CRG(platform)
|
||||
|
||||
|
|
Loading…
Reference in New Issue