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:
Florent Kermarrec 2014-09-27 15:34:28 +02:00
parent 879478a6e4
commit c27f24c4c0
6 changed files with 119 additions and 113 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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