mirror of
https://github.com/enjoy-digital/usb3_pipe.git
synced 2025-01-04 10:18:41 +08:00
206 lines
7.5 KiB
Python
Executable File
206 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
#
|
|
# This file is part of USB3-PIPE project.
|
|
#
|
|
# Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
import sys
|
|
|
|
from migen import *
|
|
|
|
from litex_boards.platforms import xilinx_kc705
|
|
|
|
from litex.build.generic_platform import *
|
|
from litex.build.xilinx import VivadoProgrammer
|
|
|
|
from litex.soc.cores.clock import *
|
|
from litex.soc.integration.soc_core import *
|
|
from litex.soc.integration.builder import *
|
|
|
|
from liteeth.phy import LiteEthPHY
|
|
|
|
from litescope import LiteScopeAnalyzer
|
|
|
|
from usb3_pipe import K7USB3SerDes, USB3PIPE
|
|
from usb3_core.core import USB3Core
|
|
|
|
# USB3 IOs -----------------------------------------------------------------------------------------
|
|
|
|
_usb3_io = [
|
|
# PCIe / Through PCIsh-to-USB3 breakout board.
|
|
("pcie_rx", 0,
|
|
Subsignal("p", Pins("M6")),
|
|
Subsignal("n", Pins("M5")),
|
|
),
|
|
("pcie_tx", 0,
|
|
Subsignal("p", Pins("L4")),
|
|
Subsignal("n", Pins("L3")),
|
|
),
|
|
|
|
# SMA
|
|
("sma_tx", 0,
|
|
Subsignal("p", Pins("K2")),
|
|
Subsignal("n", Pins("K1"))
|
|
),
|
|
("sma_rx", 0,
|
|
Subsignal("p", Pins("K6")),
|
|
Subsignal("n", Pins("K5"))
|
|
),
|
|
|
|
# SFP / Through XillyUSB's SFP2USB.
|
|
("sfp_tx", 0,
|
|
Subsignal("p", Pins("H2")),
|
|
Subsignal("n", Pins("H1")),
|
|
),
|
|
("sfp_rx", 0,
|
|
Subsignal("p", Pins("G4")),
|
|
Subsignal("n", Pins("G3")),
|
|
),
|
|
]
|
|
|
|
# CRG ----------------------------------------------------------------------------------------------
|
|
|
|
class _CRG(Module):
|
|
def __init__(self, platform, sys_clk_freq):
|
|
self.clock_domains.cd_sys = ClockDomain()
|
|
self.clock_domains.cd_oob = ClockDomain()
|
|
self.clock_domains.cd_clk125 = ClockDomain()
|
|
|
|
# # #
|
|
|
|
self.submodules.pll = pll = S7PLL(speedgrade=-2)
|
|
pll.register_clkin(platform.request("clk200"), 200e6)
|
|
pll.create_clkout(self.cd_sys, sys_clk_freq)
|
|
pll.create_clkout(self.cd_oob, sys_clk_freq/8)
|
|
pll.create_clkout(self.cd_clk125, 125e6)
|
|
|
|
# USB3SoC ------------------------------------------------------------------------------------------
|
|
|
|
class USB3SoC(SoCMini):
|
|
def __init__(self, platform, connector="sfp", with_etherbone=True, with_analyzer=True):
|
|
sys_clk_freq = int(125e6)
|
|
|
|
# SoCMini ----------------------------------------------------------------------------------
|
|
SoCMini.__init__(self, platform, sys_clk_freq, ident="USB3SoC", ident_version=True)
|
|
|
|
# CRG --------------------------------------------------------------------------------------
|
|
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
|
|
|
# UARTBone ---------------------------------------------------------------------------------
|
|
self.add_uartbone()
|
|
|
|
# Etherbone --------------------------------------------------------------------------------
|
|
if with_etherbone:
|
|
self.submodules.eth_phy = LiteEthPHY(
|
|
clock_pads = platform.request("eth_clocks"),
|
|
pads = platform.request("eth"),
|
|
clk_freq = sys_clk_freq)
|
|
self.add_etherbone(phy=self.eth_phy, ip_address="192.168.1.50")
|
|
|
|
# USB3 SerDes ------------------------------------------------------------------------------
|
|
usb3_serdes = K7USB3SerDes(platform,
|
|
sys_clk = self.crg.cd_sys.clk,
|
|
sys_clk_freq = sys_clk_freq,
|
|
refclk_pads = ClockSignal("clk125"),
|
|
refclk_freq = 125e6,
|
|
tx_pads = platform.request(connector + "_tx"),
|
|
rx_pads = platform.request(connector + "_rx"))
|
|
self.submodules += usb3_serdes
|
|
platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-52]")
|
|
|
|
# USB3 PIPE --------------------------------------------------------------------------------
|
|
usb3_pipe = USB3PIPE(serdes=usb3_serdes, sys_clk_freq=sys_clk_freq)
|
|
self.submodules.usb3_pipe = usb3_pipe
|
|
self.comb += usb3_pipe.reset.eq(platform.request("cpu_reset"))
|
|
|
|
# USB3 Core --------------------------------------------------------------------------------
|
|
usb3_core = USB3Core(platform)
|
|
self.submodules.usb3_core = usb3_core
|
|
self.comb += [
|
|
usb3_pipe.source.connect(usb3_core.sink),
|
|
usb3_core.source.connect(usb3_pipe.sink),
|
|
usb3_core.reset.eq(~usb3_pipe.ready),
|
|
]
|
|
|
|
# Debug IOs (Through CYUSB3ACC-005) --------------------------------------------------------
|
|
_debug_ios = [
|
|
("tx_idle", 0, Pins("AK20"), IOStandard("LVCMOS12")), # I2C_SDA
|
|
("rx_idle", 0, Pins("AK21"), IOStandard("LVCMOS12")), # I2C_SCL
|
|
]
|
|
self.platform.add_extension(_debug_ios)
|
|
self.comb += [
|
|
platform.request("tx_idle").eq(usb3_serdes.tx_idle),
|
|
platform.request("rx_idle").eq(usb3_serdes.rx_idle),
|
|
]
|
|
|
|
# Leds -------------------------------------------------------------------------------------
|
|
self.comb += platform.request("user_led", 0).eq(usb3_serdes.ready)
|
|
self.comb += platform.request("user_led", 1).eq(usb3_pipe.ready)
|
|
|
|
# Analyzer ---------------------------------------------------------------------------------
|
|
if with_analyzer:
|
|
analyzer_signals = [
|
|
# LFPS
|
|
usb3_serdes.tx_idle,
|
|
usb3_serdes.rx_idle,
|
|
usb3_serdes.tx_pattern,
|
|
usb3_serdes.rx_polarity,
|
|
usb3_pipe.lfps.rx_polling,
|
|
usb3_pipe.lfps.tx_polling,
|
|
|
|
# Training Sequence
|
|
usb3_pipe.ts.tx_enable,
|
|
usb3_pipe.ts.rx_ts1,
|
|
usb3_pipe.ts.rx_ts2,
|
|
usb3_pipe.ts.tx_enable,
|
|
usb3_pipe.ts.tx_tseq,
|
|
usb3_pipe.ts.tx_ts1,
|
|
usb3_pipe.ts.tx_ts2,
|
|
usb3_pipe.ts.tx_done,
|
|
|
|
# LTSSM
|
|
usb3_pipe.ltssm.polling.fsm,
|
|
usb3_pipe.ready,
|
|
|
|
# Endpoints
|
|
usb3_serdes.rx_datapath.skip_remover.skip,
|
|
usb3_serdes.source,
|
|
usb3_serdes.sink,
|
|
usb3_pipe.source,
|
|
usb3_pipe.sink,
|
|
]
|
|
self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 4096, csr_csv="analyzer.csv")
|
|
|
|
# Build --------------------------------------------------------------------------------------------
|
|
|
|
import argparse
|
|
|
|
def main():
|
|
with open("README.md") as f:
|
|
description = [str(f.readline()) for i in range(7)]
|
|
parser = argparse.ArgumentParser(description="".join(description[1:]), formatter_class=argparse.RawTextHelpFormatter)
|
|
parser.add_argument("--build", action="store_true", help="Build bitstream.")
|
|
parser.add_argument("--load", action="store_true", help="Load bitstream.")
|
|
args = parser.parse_args()
|
|
|
|
if not args.build and not args.load:
|
|
parser.print_help()
|
|
|
|
os.makedirs("build/xilinx_kc705/gateware", exist_ok=True)
|
|
os.system("cd usb3_core/daisho && make && ./usb_descrip_gen")
|
|
os.system("cp usb3_core/daisho/usb3/*.init build/xilinx_kc705/gateware/")
|
|
platform = xilinx_kc705.Platform()
|
|
platform.add_extension(_usb3_io)
|
|
soc = USB3SoC(platform)
|
|
builder = Builder(soc, csr_csv="csr.csv")
|
|
builder.build(run=args.build)
|
|
|
|
if args.load:
|
|
prog = soc.platform.create_programmer()
|
|
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|