usb3_pipe/kc705.py
2019-10-07 23:33:08 +02:00

158 lines
6.0 KiB
Python
Executable File

# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
#!/usr/bin/env python3
from migen import *
from litex.boards.platforms import kc705
from litex.build.generic_platform import *
from litex.soc.cores.clock import *
from litex.soc.interconnect.csr import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from liteeth.common import convert_ip
from liteeth.phy import LiteEthPHY
from liteeth.core import LiteEthUDPIPCore
from liteeth.frontend.etherbone import LiteEthEtherbone
from litescope import LiteScopeAnalyzer
from usb3_pipe.serdes import K7USB3SerDes
from usb3_pipe.lfps import LFPSUnit
from usb3_pipe.ordered_set import OrderedSetUnit
from usb3_pipe.ltssm import LTSSM
# USB3 IOs -----------------------------------------------------------------------------------------
_usb3_io = [
# HiTechGlobal USB3.0 FMC P3 connector
("usb3_rx", 0,
Subsignal("p", Pins("HPC:DP0_M2C_P")),
Subsignal("n", Pins("HPC:DP0_M2C_N")),
),
("usb3_tx", 0,
Subsignal("p", Pins("HPC:DP0_C2M_P")),
Subsignal("n", Pins("HPC:DP0_C2M_N")),
),
# PCIe
("pcie_rx", 0,
Subsignal("p", Pins("M6")),
Subsignal("n", Pins("M5")),
),
("pcie_tx", 0,
Subsignal("p", Pins("L4")),
Subsignal("n", Pins("L3")),
),
]
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_usb3_oob = ClockDomain()
# # #
self.submodules.pll = pll = S7PLL(speedgrade=-2)
self.comb += pll.reset.eq(platform.request("cpu_reset"))
pll.register_clkin(platform.request("clk156"), 156.5e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_usb3_oob, sys_clk_freq/8)
# USB3SoC ------------------------------------------------------------------------------------------
class USB3SoC(SoCMini):
def __init__(self, platform, connector="usb3",
with_etherbone=True, mac_address=0x10e2d5000000, ip_address="192.168.1.50",
with_analyzer=False):
sys_clk_freq = int(156.5e6)
SoCMini.__init__(self, platform, sys_clk_freq, ident="USB3SoC", ident_version=True)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# Ethernet <--> Wishbone -------------------------------------------------------------------
if with_etherbone:
# phy
self.submodules.eth_phy = LiteEthPHY(
clock_pads = platform.request("eth_clocks"),
pads = platform.request("eth"),
clk_freq = sys_clk_freq)
self.add_csr("eth_phy")
# core
self.submodules.eth_core = LiteEthUDPIPCore(
phy = self.eth_phy,
mac_address = mac_address,
ip_address = convert_ip(ip_address),
clk_freq = sys_clk_freq)
# etherbone
self.submodules.etherbone = LiteEthEtherbone(self.eth_core.udp, 1234)
self.add_wb_master(self.etherbone.wishbone.bus)
# timing constraints
self.crg.cd_sys.clk.attr.add("keep")
self.eth_phy.crg.cd_eth_rx.clk.attr.add("keep")
self.eth_phy.crg.cd_eth_tx.clk.attr.add("keep")
self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/156.5e6)
self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_rx.clk, 1e9/125e6)
self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_tx.clk, 1e9/125e6)
self.platform.add_false_path_constraints(
self.crg.cd_sys.clk,
self.eth_phy.crg.cd_eth_rx.clk,
self.eth_phy.crg.cd_eth_tx.clk)
# SerDes -----------------------------------------------------------------------------------
serdes = K7USB3SerDes(platform,
sys_clk = self.crg.cd_sys.clk,
sys_clk_freq = sys_clk_freq,
refclk_pads = platform.request("sgmii_clock"),
refclk_freq = 125e6,
tx_pads = platform.request(connector + "_tx"),
rx_pads = platform.request(connector + "_rx"))
self.submodules += serdes
# LFPS Unit --------------------------------------------------------------------------------
lfps_unit = LFPSUnit(sys_clk_freq=sys_clk_freq, serdes=serdes)
self.submodules += lfps_unit
# OrderedSet Unit --------------------------------------------------------------------------
ordered_set_unit = OrderedSetUnit(serdes=serdes)
self.submodules += ordered_set_unit
# LTSSM ------------------------------------------------------------------------------------
ltssm = LTSSM(lfps_unit=lfps_unit, ordered_set_unit=ordered_set_unit)
self.submodules += ltssm
# Leds -------------------------------------------------------------------------------------
self.comb += platform.request("user_led", 0).eq(serdes.ready)
self.comb += platform.request("user_led", 1).eq(ltssm.polling_fsm.idle)
# Analyzer ---------------------------------------------------------------------------------
if with_analyzer:
analyzer_signals = [
ltssm.polling_fsm,
serdes.source,
serdes.sink,
]
self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 4096, csr_csv="tools/analyzer.csv")
self.add_csr("analyzer")
# Build --------------------------------------------------------------------------------------------
def main():
platform = kc705.Platform()
platform.add_extension(_usb3_io)
soc = USB3SoC(platform)
builder = Builder(soc, output_dir="build", csr_csv="tools/csr.csv")
vns = builder.build()
if __name__ == "__main__":
main()