make ctrl/datapath in phy vendor agnostics and simplify imports

This commit is contained in:
Florent Kermarrec 2014-12-18 18:02:35 +01:00
parent 9789a78aab
commit 4f22bc807a
19 changed files with 401 additions and 414 deletions

View File

@ -1,5 +1,3 @@
from migen.fhdl.std import *
from lib.sata.common import *
from lib.sata.link import SATALink
from lib.sata.transport import SATATransport

View File

@ -1,6 +1,3 @@
from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
from lib.sata.common import *
from lib.sata.link.scrambler import Scrambler

View File

@ -1,7 +1,3 @@
from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
from migen.actorlib.fifo import SyncFIFO as FIFO
from lib.sata.common import *
tx_to_rx = [
@ -122,7 +118,7 @@ class SATACommandRX(Module):
###
cmd_fifo = FIFO(command_rx_cmd_description(32), 2) # Note: ideally depth=1
cmd_fifo = SyncFIFO(command_rx_cmd_description(32), 2) # Note: ideally depth=1
data_fifo = InsertReset(FIFO(command_rx_data_description(32), sector_size*max_count//4, buffered=True))
self.submodules += cmd_fifo, data_fifo

View File

@ -1,6 +1,9 @@
from migen.fhdl.std import *
from migen.genlib.resetsync import *
from migen.genlib.fsm import *
from migen.genlib.record import *
from migen.flow.actor import *
from migen.actorlib.fifo import *
# PHY / Link Layers
primitives = {

View File

@ -1,7 +1,3 @@
from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
from migen.actorlib.fifo import SyncFIFO
from lib.sata.common import *
from lib.sata.link.crc import SATACRCInserter, SATACRCChecker
from lib.sata.link.scrambler import SATAScrambler

View File

@ -1,9 +1,8 @@
from migen.fhdl.std import *
from migen.genlib.misc import optree
from lib.sata.common import *
from lib.sata.link.scrambler import Scrambler
from migen.genlib.misc import optree
class SATACONTInserter(Module):
def __init__(self, description):
self.sink = sink = Sink(description)

View File

@ -1,9 +1,8 @@
from migen.fhdl.std import *
from lib.sata.common import *
from migen.genlib.misc import optree
from migen.actorlib.crc import CRCInserter, CRCChecker
from lib.sata.common import *
class CRCEngine(Module):
"""Cyclic Redundancy Check Engine

View File

@ -1,8 +1,8 @@
from lib.sata.common import *
from migen.fhdl.std import *
from migen.genlib.misc import optree
from lib.sata.common import *
@DecorateModule(InsertCE)
class Scrambler(Module):
"""SATA Scrambler

24
lib/sata/phy/__init__.py Normal file
View File

@ -0,0 +1,24 @@
from lib.sata.common import *
from lib.sata.phy.ctrl import SATAPHYHostCtrl, SATAPHYDeviceCtrl
from lib.sata.phy.datapath import SATAPHYDatapath
class SATAPHY(Module):
def __init__(self, pads, clk_freq, host=True, device_family="k7", speed="SATA1"):
# Transceiver / Clocks
if device_family == "k7":
from lib.sata.phy.k7.trx import K7SATAPHYTRX
from lib.sata.phy.k7.crg import K7SATAPHYCRG
self.submodules.trx = K7SATAPHYTRX(pads, speed)
self.submodules.crg = K7SATAPHYCRG(pads, self.trx, clk_freq, speed)
else:
raise NotImplementedError(device_family + "device family not implemented")
# Control
if host:
self.submodules.ctrl = SATAPHYHostCtrl(self.trx, self.crg, clk_freq)
else:
self.submodules.ctrl = SATAPHYDeviceCtrl(self.trx, self.crg, clk_freq)
# Datapath
self.submodules.datapath = SATAPHYDatapath(self.trx, self.ctrl)
self.sink, self.source = self.datapath.sink, self.datapath.source

271
lib/sata/phy/ctrl.py Normal file
View File

@ -0,0 +1,271 @@
from math import ceil
from lib.sata.common import *
def us(t, clk_freq):
clk_period_us = 1000000/clk_freq
return ceil(t/clk_period_us)
class SATAPHYHostCtrlTimeout(Module):
def __init__(self, load):
self.load = Signal()
self.dec = Signal()
self.reached = Signal()
cnt = Signal(max=load+1)
self.sync += \
If(self.load,
cnt.eq(load)
).Elif(self.dec & ~self.reached,
cnt.eq(cnt-1)
)
self.comb += self.reached.eq(cnt == 0)
class SATAPHYHostCtrl(Module):
def __init__(self, trx, crg, clk_freq):
self.ready = Signal()
self.sink = sink = Sink(phy_description(32))
self.source = source = Source(phy_description(32))
###
self.comb += [
source.stb.eq(1),
sink.ack.eq(1)
]
retry_timeout = SATAPHYHostCtrlTimeout(us(10000, clk_freq))
align_timeout = SATAPHYHostCtrlTimeout(us(873, clk_freq))
self.submodules += align_timeout, retry_timeout
align_detect = Signal()
non_align_cnt = Signal(4)
fsm = FSM(reset_state="RESET")
self.submodules += fsm
fsm.act("RESET",
trx.tx_idle.eq(1),
retry_timeout.load.eq(1),
align_timeout.load.eq(1),
If(crg.ready,
NextState("COMINIT")
),
)
fsm.act("COMINIT",
trx.tx_idle.eq(1),
trx.tx_cominit_stb.eq(1),
If(trx.tx_cominit_ack & ~trx.rx_cominit_stb,
NextState("AWAIT_COMINIT")
),
)
fsm.act("AWAIT_COMINIT",
trx.tx_idle.eq(1),
retry_timeout.dec.eq(1),
If(trx.rx_cominit_stb,
NextState("AWAIT_NO_COMINIT")
).Else(
If(retry_timeout.reached,
NextState("RESET")
)
),
)
fsm.act("AWAIT_NO_COMINIT",
trx.tx_idle.eq(1),
retry_timeout.load.eq(1),
If(~trx.rx_cominit_stb,
NextState("CALIBRATE")
),
)
fsm.act("CALIBRATE",
trx.tx_idle.eq(1),
NextState("COMWAKE"),
)
fsm.act("COMWAKE",
trx.tx_idle.eq(1),
trx.tx_comwake_stb.eq(1),
If(trx.tx_comwake_ack,
NextState("AWAIT_COMWAKE")
),
)
fsm.act("AWAIT_COMWAKE",
trx.tx_idle.eq(1),
retry_timeout.dec.eq(1),
If(trx.rx_comwake_stb,
NextState("AWAIT_NO_COMWAKE")
).Else(
If(retry_timeout.reached,
NextState("RESET")
)
),
)
fsm.act("AWAIT_NO_COMWAKE",
trx.tx_idle.eq(1),
If(~trx.rx_comwake_stb,
NextState("AWAIT_NO_RX_IDLE")
),
)
fsm.act("AWAIT_NO_RX_IDLE",
trx.tx_idle.eq(0),
source.data.eq(0x4A4A4A4A), #D10.2
source.charisk.eq(0b0000),
If(~trx.rx_idle,
NextState("AWAIT_ALIGN"),
crg.reset.eq(1),
trx.pmarxreset.eq(1)
),
)
fsm.act("AWAIT_ALIGN",
trx.tx_idle.eq(0),
source.data.eq(0x4A4A4A4A), #D10.2
source.charisk.eq(0b0000),
trx.rx_align.eq(1),
align_timeout.dec.eq(1),
If(align_detect & ~trx.rx_idle,
NextState("SEND_ALIGN")
).Elif(align_timeout.reached,
NextState("RESET")
),
)
fsm.act("SEND_ALIGN",
trx.tx_idle.eq(0),
trx.rx_align.eq(1),
source.data.eq(primitives["ALIGN"]),
source.charisk.eq(0b0001),
If(non_align_cnt == 3,
NextState("READY")
),
)
fsm.act("READY",
trx.tx_idle.eq(0),
trx.rx_align.eq(1),
source.data.eq(primitives["SYNC"]),
source.charisk.eq(0b0001),
If(trx.rx_idle,
NextState("RESET")
),
self.ready.eq(1),
)
self.comb += \
align_detect.eq(self.sink.stb & (self.sink.data == primitives["ALIGN"]))
self.sync += \
If(fsm.ongoing("SEND_ALIGN"),
If(sink.stb,
If(sink.data[0:8] == 0x7C,
non_align_cnt.eq(non_align_cnt + 1)
).Else(
non_align_cnt.eq(0)
)
)
)
class SATAPHYDeviceCtrl(Module):
def __init__(self, trx, crg, clk_freq):
self.ready = Signal()
sink = Sink(phy_description(32))
source = Source(phy_description(32))
###
self.comb += [
source.stb.eq(1),
sink.ack.eq(1)
]
retry_timeout = SATAPHYHostCtrlTimeout(us(10000, clk_freq))
align_timeout = SATAPHYHostCtrlTimeout(us(873, clk_freq))
self.submodules += align_timeout, retry_timeout
fsm = FSM(reset_state="RESET")
self.submodules += fsm
fsm.act("RESET",
trx.tx_idle.eq(1),
retry_timeout.load.eq(1),
align_timeout.load.eq(1),
If(crg.ready,
NextState("AWAIT_COMINIT")
)
)
fsm.act("AWAIT_COMINIT",
trx.tx_idle.eq(1),
If(trx.rx_cominit_stb,
NextState("AWAIT_NO_COMINIT")
)
)
fsm.act("AWAIT_NO_COMINIT",
trx.tx_idle.eq(1),
If(~trx.rx_cominit_stb,
NextState("COMINIT")
)
)
fsm.act("COMINIT",
trx.tx_idle.eq(1),
trx.tx_cominit_stb.eq(1),
If(trx.tx_cominit_ack,
NextState("AWAIT_COMWAKE")
)
)
fsm.act("AWAIT_COMWAKE",
trx.tx_idle.eq(1),
retry_timeout.dec.eq(1),
If(trx.rx_comwake_stb,
NextState("AWAIT_NO_COMWAKE")
).Else(
If(retry_timeout.reached,
NextState("RESET")
)
)
)
fsm.act("AWAIT_NO_COMWAKE",
trx.tx_idle.eq(1),
If(~trx.rx_comwake_stb,
NextState("CALIBRATE")
)
)
fsm.act("CALIBRATE",
trx.tx_idle.eq(1),
NextState("COMWAKE")
)
fsm.act("COMWAKE",
trx.tx_idle.eq(1),
trx.tx_comwake_stb.eq(1),
If(trx.tx_comwake_stb,
NextState("RESET_CRG"),
crg.reset.eq(1),
)
)
fsm.act("RESET_CRG",
trx.tx_idle.eq(0),
If(crg.ready,
NextState("SEND_ALIGN")
)
)
fsm.act("SEND_ALIGN",
trx.tx_idle.eq(0),
trx.rx_align.eq(1),
source.data.eq(primitives["ALIGN"]),
source.charisk.eq(0b0001),
align_timeout.dec.eq(1),
If(align_detect,
NextState("READY")
).Elif(align_timeout.reached,
NextState("ERROR")
)
)
fsm.act("READY",
trx.tx_idle.eq(0),
NextState("READY"),
If(trx.rx_idle,
NextState("RESET")
),
self.ready.eq(1)
)
fsm.act("ERROR",
trx.tx_idle.eq(1),
NextState("RESET")
)
self.comb += \
align_detect.eq(sink.stb & (sink.data == primitives["ALIGN"]))

View File

@ -1,11 +1,8 @@
from migen.fhdl.std import *
from migen.genlib.misc import chooser
from migen.actorlib.fifo import AsyncFIFO
from migen.flow.actor import Sink, Source
from lib.sata.common import *
class K7SATAPHYDatapathRX(Module):
from migen.genlib.misc import chooser
class SATAPHYDatapathRX(Module):
def __init__(self):
self.sink = Sink(phy_description(16))
self.source = Source(phy_description(32))
@ -69,7 +66,7 @@ class K7SATAPHYDatapathRX(Module):
]
self.comb += Record.connect(fifo.source, self.source)
class K7SATAPHYDatapathTX(Module):
class SATAPHYDatapathTX(Module):
def __init__(self):
self.sink = Sink(phy_description(32))
self.source = Source(phy_description(16))
@ -108,23 +105,20 @@ class K7SATAPHYDatapathTX(Module):
chooser(fifo.source.charisk, mux, self.source.charisk)
]
class K7SATAPHYDatapath(Module):
def __init__(self, gtx, ctrl):
class SATAPHYDatapath(Module):
def __init__(self, trx, ctrl):
self.sink = Sink(phy_description(32))
self.source = Source(phy_description(32))
###
# change data width & cross domain crossing
rx = K7SATAPHYDatapathRX()
tx = K7SATAPHYDatapathTX()
rx = SATAPHYDatapathRX()
tx = SATAPHYDatapathTX()
self.submodules += rx, tx
self.comb += [
rx.sink.data.eq(gtx.rxdata),
rx.sink.charisk.eq(gtx.rxcharisk),
gtx.txdata.eq(tx.source.data),
gtx.txcharisk.eq(tx.source.charisk),
trx.source.connect(rx.sink),
tx.source.connect(trx.sink)
]
# Align cnt (send 2 Align DWORDs every 256 DWORDs)

View File

@ -1,14 +1,10 @@
from math import ceil
from migen.fhdl.std import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.fsm import FSM, NextState
from lib.sata.common import *
from lib.sata.phy.k7sataphy.gtx import GTXE2_COMMON
from lib.sata.phy.k7.trx import GTXE2_COMMON
class K7SATAPHYCRG(Module):
def __init__(self, pads, gtx, clk_freq, default_speed):
def __init__(self, pads, gtx, clk_freq, speed):
self.reset = Signal()
self.ready = Signal()
@ -51,7 +47,7 @@ class K7SATAPHYCRG(Module):
"SATA2" : 8.0,
"SATA3" : 4.0
}
mmcm_div = mmcm_div_config[default_speed]
mmcm_div = mmcm_div_config[speed]
self.specials += [
Instance("BUFG", i_I=gtx.txoutclk, o_O=mmcm_clk_i),
Instance("MMCME2_ADV",

View File

@ -1,8 +1,7 @@
from migen.fhdl.std import *
from migen.genlib.cdc import *
from lib.sata.common import *
from migen.genlib.cdc import *
def ones(width):
return 2**width-1
@ -14,9 +13,35 @@ class _PulseSynchronizer(PulseSynchronizer):
o.eq(self.o)
]
class K7SATAPHYGTX(Module):
def __init__(self, pads, default_speed):
# Interface
class _RisingEdge(Module):
def __init__(self, i, o):
i_d = Signal()
self.sync += i_d.eq(i)
self.comb += o.eq(i & ~i_d)
class K7SATAPHYTRX(Module):
def __init__(self, pads, speed):
# Common signals
# control
self.tx_idle = Signal() #i
self.tx_cominit_stb = Signal() #i
self.tx_cominit_ack = Signal() #o
self.tx_comwake_stb = Signal() #i
self.tx_comwake_ack = Signal() #o
self.rx_idle = Signal() #o
self.rx_align = Signal() #i
self.rx_cominit_stb = Signal() #o
self.rx_comwake_stb = Signal() #o
# datapath
self.sink = Sink(phy_description(16))
self.source = Source(phy_description(16))
# K7 specific signals
# Channel - Ref Clock Ports
self.gtrefclk0 = Signal()
@ -82,15 +107,40 @@ class K7SATAPHYGTX(Module):
"SATA2" : 2,
"SATA3" : 1
}
rxout_div = div_config[default_speed]
txout_div = div_config[default_speed]
rxout_div = div_config[speed]
txout_div = div_config[speed]
cdr_config = {
"SATA1" : 0x0380008BFF40100008,
"SATA2" : 0x0388008BFF40200008,
"SATA3" : 0X0380008BFF10200010
}
rxcdr_cfg = cdr_config[default_speed]
rxcdr_cfg = cdr_config[speed]
# Specific / Generic signals encoding/decoding
self.comb += [
self.txelecidle.eq(self.tx_idle),
self.tx_cominit_ack.eq(self.tx_cominit_stb & self.txcomfinish),
self.tx_comwake_ack.eq(self.tx_comwake_stb & self.txcomfinish),
self.rx_idle.eq(self.rxelecidle),
self.rxalign.eq(self.rx_align),
self.rx_cominit_stb.eq(self.rxcominitdet),
self.rx_comwake_stb.eq(self.rxcomwakedet),
]
self.submodules += [
_RisingEdge(self.tx_cominit_stb, self.txcominit),
_RisingEdge(self.tx_comwake_stb, self.txcomwake),
]
self.comb += [
self.txcharisk.eq(self.sink.charisk),
self.txdata.eq(self.sink.data),
self.sink.ack.eq(1),
self.source.stb.eq(1),
self.source.charisk.eq(self.rxcharisk),
self.source.data.eq(self.rxdata)
]
# Internals and clock domain crossing
# sys_clk --> sata_tx clk

View File

@ -1,23 +0,0 @@
from migen.fhdl.std import *
from lib.sata.common import *
from lib.sata.phy.k7sataphy.gtx import K7SATAPHYGTX
from lib.sata.phy.k7sataphy.crg import K7SATAPHYCRG
from lib.sata.phy.k7sataphy.ctrl import K7SATAPHYHostCtrl, K7SATAPHYDeviceCtrl
from lib.sata.phy.k7sataphy.datapath import K7SATAPHYDatapath
class K7SATAPHY(Module):
def __init__(self, pads, clk_freq, host=True, default_speed="SATA1"):
# GTX
self.submodules.gtx = K7SATAPHYGTX(pads, default_speed)
# CRG / CTRL
self.submodules.crg = K7SATAPHYCRG(pads, self.gtx, clk_freq, default_speed)
if host:
self.submodules.ctrl = K7SATAPHYHostCtrl(self.gtx, self.crg, clk_freq)
else:
self.submodules.ctrl = K7SATAPHYDeviceCtrl(self.gtx, self.crg, clk_freq)
# DATAPATH
self.submodules.datapath = K7SATAPHYDatapath(self.gtx, self.ctrl)
self.sink, self.source = self.datapath.sink, self.datapath.source

View File

@ -1,307 +0,0 @@
from math import ceil
from migen.fhdl.std import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.fsm import FSM, NextState
from migen.flow.actor import Sink, Source
from lib.sata.common import *
def us(t, clk_freq):
clk_period_us = 1000000/clk_freq
return ceil(t/clk_period_us)
class K7SATAPHYHostCtrl(Module):
def __init__(self, gtx, crg, clk_freq):
self.ready = Signal()
self.sink = Sink(phy_description(32))
self.source = Source(phy_description(32))
self.align_detect = align_detect = Signal()
align_timeout_cnt = Signal(32)
align_timeout = Signal()
retry_timeout_cnt = Signal(32)
retry_timeout = Signal()
non_align_cnt = Signal(4)
txcominit = Signal()
txcomwake = Signal()
self.comb += [
self.source.stb.eq(1),
self.sink.ack.eq(1)
]
fsm = FSM(reset_state="RESET")
self.submodules += fsm
fsm.act("RESET",
gtx.txelecidle.eq(1),
If(crg.ready,
NextState("COMINIT")
),
)
fsm.act("COMINIT",
gtx.txelecidle.eq(1),
txcominit.eq(1),
If(gtx.txcomfinish & ~gtx.rxcominitdet,
NextState("AWAIT_COMINIT")
),
)
fsm.act("AWAIT_COMINIT",
gtx.txelecidle.eq(1),
If(gtx.rxcominitdet,
NextState("AWAIT_NO_COMINIT")
).Else(
If(retry_timeout,
NextState("RESET")
)
),
)
fsm.act("AWAIT_NO_COMINIT",
gtx.txelecidle.eq(1),
If(~gtx.rxcominitdet,
NextState("CALIBRATE")
),
)
fsm.act("CALIBRATE",
gtx.txelecidle.eq(1),
NextState("COMWAKE"),
)
fsm.act("COMWAKE",
gtx.txelecidle.eq(1),
txcomwake.eq(1),
If(gtx.txcomfinish,
NextState("AWAIT_COMWAKE")
),
)
fsm.act("AWAIT_COMWAKE",
gtx.txelecidle.eq(1),
If(gtx.rxcomwakedet,
NextState("AWAIT_NO_COMWAKE")
).Else(
If(retry_timeout,
NextState("RESET")
)
),
)
fsm.act("AWAIT_NO_COMWAKE",
gtx.txelecidle.eq(1),
If(~gtx.rxcomwakedet,
NextState("AWAIT_NO_RXELECIDLE")
),
)
fsm.act("AWAIT_NO_RXELECIDLE",
gtx.txelecidle.eq(0),
self.source.data.eq(0x4A4A4A4A), #D10.2
self.source.charisk.eq(0b0000),
If(~gtx.rxelecidle,
NextState("AWAIT_ALIGN"),
crg.reset.eq(1),
gtx.pmarxreset.eq(1)
),
)
fsm.act("AWAIT_ALIGN",
gtx.txelecidle.eq(0),
self.source.data.eq(0x4A4A4A4A), #D10.2
self.source.charisk.eq(0b0000),
gtx.rxalign.eq(1),
If((align_detect & ~gtx.rxelecidle) & ~align_timeout,
NextState("SEND_ALIGN")
).Elif(~align_detect & align_timeout,
NextState("RESET")
),
)
fsm.act("SEND_ALIGN",
gtx.txelecidle.eq(0),
gtx.rxalign.eq(1),
self.source.data.eq(primitives["ALIGN"]),
self.source.charisk.eq(0b0001),
If(non_align_cnt == 3,
NextState("READY")
),
)
fsm.act("READY",
gtx.txelecidle.eq(0),
gtx.rxalign.eq(1),
self.source.data.eq(primitives["SYNC"]),
self.source.charisk.eq(0b0001),
If(gtx.rxelecidle,
NextState("RESET")
),
self.ready.eq(1),
)
txcominit_d = Signal()
txcomwake_d = Signal()
self.sync += [
txcominit_d.eq(txcominit),
txcomwake_d.eq(txcomwake),
gtx.txcominit.eq(txcominit & ~txcominit_d),
gtx.txcomwake.eq(txcomwake & ~txcomwake_d),
]
self.comb += align_detect.eq(self.sink.stb & (self.sink.data == primitives["ALIGN"]));
self.sync += \
If(fsm.ongoing("RESET"),
align_timeout_cnt.eq(us(873, clk_freq))
).Elif(fsm.ongoing("AWAIT_ALIGN"),
align_timeout_cnt.eq(align_timeout_cnt-1)
)
self.comb += align_timeout.eq(align_timeout_cnt == 0)
self.sync += \
If(fsm.ongoing("RESET") | fsm.ongoing("AWAIT_NO_COMINIT"),
retry_timeout_cnt.eq(us(10000, clk_freq))
).Elif(fsm.ongoing("AWAIT_COMINIT") | fsm.ongoing("AWAIT_COMWAKE"),
retry_timeout_cnt.eq(retry_timeout_cnt-1)
)
self.comb += retry_timeout.eq(retry_timeout_cnt == 0)
self.sync += \
If(fsm.ongoing("SEND_ALIGN"),
If(self.sink.stb,
If(self.sink.data[0:8] == 0x7C,
non_align_cnt.eq(non_align_cnt + 1)
).Else(
non_align_cnt.eq(0)
)
)
)
class K7SATAPHYDeviceCtrl(Module):
def __init__(self, gtx, crg, clk_freq):
self.ready = Signal()
self.sink = Sink(phy_description(32))
self.source = Source(phy_description(32))
align_detect = Signal()
align_timeout = Signal()
align_timeout_cnt = Signal(32)
retry_timeout_cnt = Signal(32)
retry_timeout = Signal()
txcominit = Signal()
txcomwake = Signal()
self.comb += [
self.source.stb.eq(1),
self.sink.ack.eq(1)
]
fsm = FSM(reset_state="RESET")
self.submodules += fsm
fsm.act("RESET",
gtx.txelecidle.eq(1),
If(crg.ready,
NextState("AWAIT_COMINIT")
)
)
fsm.act("AWAIT_COMINIT",
gtx.txelecidle.eq(1),
If(gtx.rxcominitdet,
NextState("AWAIT_NO_COMINIT")
)
)
fsm.act("AWAIT_NO_COMINIT",
gtx.txelecidle.eq(1),
If(~gtx.rxcominitdet,
NextState("COMINIT")
)
)
fsm.act("COMINIT",
gtx.txelecidle.eq(1),
txcominit.eq(1),
If(gtx.txcomfinish,
NextState("AWAIT_COMWAKE")
)
)
fsm.act("AWAIT_COMWAKE",
gtx.txelecidle.eq(1),
If(gtx.rxcomwakedet,
NextState("AWAIT_NO_COMWAKE")
).Else(
If(retry_timeout,
NextState("RESET")
)
)
)
fsm.act("AWAIT_NO_COMWAKE",
gtx.txelecidle.eq(1),
If(~gtx.rxcomwakedet,
NextState("CALIBRATE")
)
)
fsm.act("CALIBRATE",
gtx.txelecidle.eq(1),
NextState("COMWAKE")
)
fsm.act("COMWAKE",
gtx.txelecidle.eq(1),
txcomwake.eq(1),
If(gtx.txcomfinish,
NextState("RESET_CRG"),
crg.reset.eq(1),
)
)
fsm.act("RESET_CRG",
gtx.txelecidle.eq(0),
If(crg.ready,
NextState("SEND_ALIGN")
)
)
fsm.act("SEND_ALIGN",
gtx.txelecidle.eq(0),
gtx.rxalign.eq(1),
self.source.data.eq(primitives["ALIGN"]),
self.source.charisk.eq(0b0001),
If(align_detect,
NextState("READY")
).Elif(align_timeout,
NextState("ERROR")
)
)
fsm.act("READY",
gtx.txelecidle.eq(0),
NextState("READY"),
If(gtx.rxelecidle,
NextState("RESET")
),
self.ready.eq(1)
)
fsm.act("ERROR",
gtx.txelecidle.eq(1),
NextState("RESET")
)
txcominit_d = Signal()
txcomwake_d = Signal()
self.sync += [
txcominit_d.eq(txcominit),
txcomwake_d.eq(txcomwake),
gtx.txcominit.eq(txcominit & ~txcominit_d),
gtx.txcomwake.eq(txcomwake & ~txcomwake_d),
]
self.comb += align_detect.eq(self.sink.stb & (self.sink.data == primitives["ALIGN"]));
self.sync += \
If(fsm.ongoing("RESET"),
align_timeout_cnt.eq(us(55, clk_freq))
).Elif(fsm.ongoing("AWAIT_ALIGN"),
align_timeout_cnt.eq(align_timeout_cnt-1)
)
self.comb += align_timeout.eq(align_timeout_cnt == 0)
self.sync += \
If(fsm.ongoing("RESET"),
retry_timeout_cnt.eq(us(10000, clk_freq))
).Elif(fsm.ongoing("AWAIT_COMWAKE"),
retry_timeout_cnt.eq(retry_timeout_cnt-1)
)
self.comb += retry_timeout.eq(retry_timeout_cnt == 0)

View File

@ -1,7 +1,5 @@
import random, copy
from migen.fhdl.std import *
from migen.genlib.record import *
from migen.sim.generic import run_simulation
from lib.sata.common import *

View File

@ -1,6 +1,3 @@
from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
from lib.sata.common import *
def _get_item(obj, name, width):

View File

@ -9,7 +9,7 @@ from miscope.uart2wishbone import UART2Wishbone
from misoclib import identifier
from lib.sata.common import *
from lib.sata.phy.k7sataphy import K7SATAPHY
from lib.sata.phy import SATAPHY
from lib.sata.link.cont import SATACONTInserter, SATACONTRemover
from migen.genlib.cdc import *
@ -111,17 +111,17 @@ class SimDesign(UART2WB):
UART2WB.__init__(self, platform, clk_freq)
self.submodules.crg = _CRG(platform)
self.submodules.sataphy_host = K7SATAPHY(platform.request("sata_host"), clk_freq, host=True)
self.submodules.sata_phy_host = SATAPHY(platform.request("sata_host"), clk_freq, host=True)
self.comb += [
self.sataphy_host.sink.stb.eq(1),
self.sataphy_host.sink.data.eq(primitives["SYNC"]),
self.sataphy_host.sink.charisk.eq(0b0001)
self.sata_phy_host.sink.stb.eq(1),
self.sata_phy_host.sink.data.eq(primitives["SYNC"]),
self.sata_phy_host.sink.charisk.eq(0b0001)
]
self.submodules.sataphy_device = K7SATAPHY(platform.request("sata_device"), clk_freq, host=False)
self.submodules.sata_phy_device = SATAPHY(platform.request("sata_device"), clk_freq, host=False)
self.comb += [
self.sataphy_device.sink.stb.eq(1),
self.sataphy_device.sink.data.eq(primitives["SYNC"]),
self.sataphy_device.sink.charisk.eq(0b0001)
self.sata_phy_device.sink.stb.eq(1),
self.sata_phy_device.sink.data.eq(primitives["SYNC"]),
self.sata_phy_device.sink.charisk.eq(0b0001)
]
@ -187,7 +187,7 @@ class TestDesign(UART2WB, AutoCSR):
UART2WB.__init__(self, platform, clk_freq)
self.submodules.crg = _CRG(platform)
self.submodules.sata_phy = K7SATAPHY(platform.request("sata_host"), clk_freq, host=True, default_speed="SATA1")
self.submodules.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, host=True, speed="SATA1")
self.submodules.stim = VeryBasicPHYStim(self.sata_phy)
self.submodules.clock_leds = ClockLeds(platform)
@ -196,29 +196,28 @@ class TestDesign(UART2WB, AutoCSR):
import os
from miscope import MiLa, Term, UART2Wishbone
gtx = self.sata_phy.gtx
trx = self.sata_phy.trx
ctrl = self.sata_phy.ctrl
crg = self.sata_phy.crg
debug = (
gtx.rxresetdone,
gtx.txresetdone,
trx.rxresetdone,
trx.txresetdone,
gtx.rxuserrdy,
gtx.txuserrdy,
trx.rxuserrdy,
trx.txuserrdy,
gtx.rxelecidle,
gtx.rxcominitdet,
gtx.rxcomwakedet,
trx.rxelecidle,
trx.rxcominitdet,
trx.rxcomwakedet,
gtx.txcomfinish,
gtx.txcominit,
gtx.txcomwake,
trx.txcomfinish,
trx.txcominit,
trx.txcomwake,
ctrl.sink.stb,
ctrl.ready,
ctrl.sink.data,
ctrl.sink.charisk,
ctrl.align_detect,
self.sata_phy.source.stb,
self.sata_phy.source.data,

View File

@ -4,8 +4,8 @@ from miscope.host.drivers import MiLaDriver
mila = MiLaDriver(wb.regs, "mila", use_rle=False)
wb.open()
###
trigger0 = mila.gtx_rxelecidle0_o*0
mask0 = mila.gtx_rxelecidle0_m
trigger0 = mila.trx_rxelecidle0_o*0
mask0 = mila.trx_rxelecidle0_m
#trigger0 = mila.ctrl_align_detect_o
#mask0 = mila.ctrl_align_detect_m