2019-10-15 15:48:12 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2019-10-07 17:53:47 +02:00
|
|
|
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
|
|
# License: BSD
|
|
|
|
|
2019-11-13 10:13:05 +01:00
|
|
|
import sys
|
|
|
|
|
2019-10-07 12:49:11 +02:00
|
|
|
from migen import *
|
|
|
|
|
|
|
|
from litex.build.generic_platform import *
|
2019-11-13 10:13:05 +01:00
|
|
|
from litex.build.xilinx import VivadoProgrammer
|
2019-10-07 12:49:11 +02:00
|
|
|
from litex.build.xilinx import XilinxPlatform
|
|
|
|
|
|
|
|
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 litex.soc.cores.uart import UARTWishboneBridge
|
|
|
|
|
|
|
|
|
|
|
|
from litescope import LiteScopeAnalyzer
|
|
|
|
|
2019-10-09 12:17:30 +02:00
|
|
|
from usb3_pipe import A7USB3SerDes, USB3PIPE
|
2019-11-22 12:59:50 +01:00
|
|
|
from usb3_core.core import USB3Core
|
2019-10-07 12:49:11 +02:00
|
|
|
|
|
|
|
# IOs ----------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
_io = [
|
|
|
|
("clk100", 0, Pins("R4"), IOStandard("LVCMOS33")),
|
|
|
|
|
|
|
|
("user_led", 0, Pins("AB1"), IOStandard("LVCMOS33")),
|
|
|
|
("user_led", 1, Pins("AB8"), IOStandard("LVCMOS33")),
|
|
|
|
|
|
|
|
("user_btn", 0, Pins("AA1"), IOStandard("LVCMOS33")),
|
|
|
|
("user_btn", 1, Pins("AB6"), IOStandard("LVCMOS33")),
|
|
|
|
|
2019-11-08 14:35:17 +01:00
|
|
|
("user_gpio", 0, Pins("Y6"), IOStandard("LVCMOS33")),
|
|
|
|
("user_gpio", 1, Pins("AA6"), IOStandard("LVCMOS33")),
|
|
|
|
|
2019-10-07 12:49:11 +02:00
|
|
|
("serial", 0,
|
|
|
|
Subsignal("tx", Pins("T1")),
|
|
|
|
Subsignal("rx", Pins("U1")),
|
|
|
|
IOStandard("LVCMOS33"),
|
|
|
|
),
|
|
|
|
|
|
|
|
("pcie_tx", 0,
|
|
|
|
Subsignal("p", Pins("B6")),
|
|
|
|
Subsignal("n", Pins("A6")),
|
|
|
|
),
|
|
|
|
|
|
|
|
("pcie_rx", 0,
|
|
|
|
Subsignal("p", Pins("B10")),
|
|
|
|
Subsignal("n", Pins("A10")),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|
|
|
|
# Platform -----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class Platform(XilinxPlatform):
|
|
|
|
def __init__(self):
|
|
|
|
XilinxPlatform.__init__(self, "xc7a35t-fgg484-2", _io, toolchain="vivado")
|
|
|
|
|
|
|
|
# CRG ----------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class _CRG(Module):
|
|
|
|
def __init__(self, platform, sys_clk_freq):
|
|
|
|
self.clock_domains.cd_sys = ClockDomain()
|
2019-11-08 14:35:17 +01:00
|
|
|
self.clock_domains.cd_usb3_oob = ClockDomain()
|
2019-10-07 12:49:11 +02:00
|
|
|
self.clock_domains.cd_clk125 = ClockDomain()
|
|
|
|
|
|
|
|
# # #
|
|
|
|
|
|
|
|
clk100 = platform.request("clk100")
|
2019-10-07 15:21:29 +02:00
|
|
|
platform.add_period_constraint(clk100, 1e9/100e6)
|
2019-10-07 12:49:11 +02:00
|
|
|
|
|
|
|
self.cd_sys.clk.attr.add("keep")
|
|
|
|
self.cd_clk125.clk.attr.add("keep")
|
|
|
|
|
|
|
|
self.submodules.pll = pll = S7PLL(speedgrade=-2)
|
|
|
|
pll.register_clkin(clk100, 100e6)
|
|
|
|
pll.create_clkout(self.cd_sys, sys_clk_freq)
|
2019-11-08 14:35:17 +01:00
|
|
|
pll.create_clkout(self.cd_usb3_oob, sys_clk_freq/8)
|
2019-10-07 12:49:11 +02:00
|
|
|
pll.create_clkout(self.cd_clk125, 125e6)
|
|
|
|
|
|
|
|
# USB3SoC ------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class USB3SoC(SoCMini):
|
2019-10-09 12:12:48 +02:00
|
|
|
def __init__(self, platform, with_analyzer=False):
|
2019-10-07 12:49:11 +02:00
|
|
|
|
2019-11-13 10:47:33 +01:00
|
|
|
sys_clk_freq = int(150e6)
|
2019-10-07 12:49:11 +02:00
|
|
|
SoCMini.__init__(self, platform, sys_clk_freq, ident="USB3SoC", ident_version=True)
|
|
|
|
|
|
|
|
# CRG --------------------------------------------------------------------------------------
|
|
|
|
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
|
|
|
|
|
|
|
# Serial bridge ----------------------------------------------------------------------------
|
|
|
|
self.submodules.serial_bridge = UARTWishboneBridge(platform.request("serial"), sys_clk_freq)
|
|
|
|
self.add_wb_master(self.serial_bridge.wishbone)
|
|
|
|
|
2019-10-08 08:50:13 +02:00
|
|
|
# USB3 SerDes ------------------------------------------------------------------------------
|
|
|
|
usb3_serdes = A7USB3SerDes(platform,
|
2019-10-07 17:16:57 +02:00
|
|
|
sys_clk = self.crg.cd_sys.clk,
|
|
|
|
sys_clk_freq = sys_clk_freq,
|
|
|
|
refclk_pads = ClockSignal("clk125"),
|
|
|
|
refclk_freq = 125e6,
|
|
|
|
tx_pads = platform.request("pcie_tx"),
|
|
|
|
rx_pads = platform.request("pcie_rx"))
|
2019-10-08 08:50:13 +02:00
|
|
|
self.submodules += usb3_serdes
|
2019-11-08 14:35:17 +01:00
|
|
|
platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]")
|
2019-10-07 12:49:11 +02:00
|
|
|
|
2019-11-22 12:59:50 +01:00
|
|
|
# USB3 PIPE --------------------------------------------------------------------------------
|
2019-10-09 12:12:48 +02:00
|
|
|
usb3_pipe = USB3PIPE(serdes=usb3_serdes, sys_clk_freq=sys_clk_freq)
|
2019-11-22 12:59:50 +01:00
|
|
|
self.submodules.usb3_pipe = usb3_pipe
|
2019-11-11 07:53:24 +01:00
|
|
|
self.comb += usb3_pipe.reset.eq(~platform.request("user_btn", 0))
|
2019-11-22 12:59:50 +01:00
|
|
|
|
|
|
|
# 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),
|
|
|
|
]
|
|
|
|
self.add_csr("usb3_core")
|
2019-10-07 12:49:11 +02:00
|
|
|
|
2019-10-07 23:30:54 +02:00
|
|
|
# Leds -------------------------------------------------------------------------------------
|
2019-10-08 08:50:13 +02:00
|
|
|
self.comb += platform.request("user_led", 0).eq(usb3_serdes.ready)
|
2019-10-09 12:12:48 +02:00
|
|
|
self.comb += platform.request("user_led", 1).eq(usb3_pipe.ready)
|
2019-10-07 12:49:11 +02:00
|
|
|
|
2019-10-07 23:30:54 +02:00
|
|
|
# Analyzer ---------------------------------------------------------------------------------
|
|
|
|
if with_analyzer:
|
2019-10-07 12:49:11 +02:00
|
|
|
analyzer_signals = [
|
2019-10-08 11:29:39 +02:00
|
|
|
# LFPS
|
|
|
|
usb3_serdes.tx_idle,
|
|
|
|
usb3_serdes.rx_idle,
|
|
|
|
usb3_serdes.tx_pattern,
|
2019-10-08 14:11:16 +02:00
|
|
|
usb3_serdes.rx_polarity,
|
2019-10-09 12:12:48 +02:00
|
|
|
usb3_pipe.lfps.rx_polling,
|
|
|
|
usb3_pipe.lfps.tx_polling,
|
2019-10-08 11:29:39 +02:00
|
|
|
|
|
|
|
# Training Sequence
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_pipe.ts.tx_enable,
|
2019-10-09 12:12:48 +02:00
|
|
|
usb3_pipe.ts.rx_ts1,
|
|
|
|
usb3_pipe.ts.rx_ts2,
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_pipe.ts.tx_enable,
|
|
|
|
usb3_pipe.ts.tx_tseq,
|
|
|
|
usb3_pipe.ts.tx_ts1,
|
2019-10-09 12:12:48 +02:00
|
|
|
usb3_pipe.ts.tx_ts2,
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_pipe.ts.tx_done,
|
2019-10-08 11:29:39 +02:00
|
|
|
|
|
|
|
# LTSSM
|
2019-10-16 15:51:35 +02:00
|
|
|
usb3_pipe.ltssm.polling.fsm,
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_pipe.ready,
|
2019-10-08 11:29:39 +02:00
|
|
|
|
|
|
|
# Endpoints
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_serdes.rx_datapath.skip_remover.skip,
|
2019-10-08 08:50:13 +02:00
|
|
|
usb3_serdes.source,
|
|
|
|
usb3_serdes.sink,
|
2019-11-27 18:38:34 +01:00
|
|
|
usb3_pipe.source,
|
|
|
|
usb3_pipe.sink,
|
2019-10-07 12:49:11 +02:00
|
|
|
]
|
2019-10-07 23:30:54 +02:00
|
|
|
self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 4096, csr_csv="tools/analyzer.csv")
|
|
|
|
self.add_csr("analyzer")
|
2019-10-07 12:49:11 +02:00
|
|
|
|
2019-11-13 10:13:05 +01:00
|
|
|
# Load ---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
def load():
|
|
|
|
prog = VivadoProgrammer()
|
|
|
|
prog.load_bitstream("build/gateware/top.bit")
|
|
|
|
exit()
|
|
|
|
|
2019-10-07 12:49:11 +02:00
|
|
|
# Build --------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
def main():
|
2019-11-13 10:13:05 +01:00
|
|
|
if "load" in sys.argv[1:]:
|
|
|
|
load()
|
2019-11-29 13:00:15 +01:00
|
|
|
os.system("cd usb3_core/daisho && make && ./usb_descrip_gen")
|
2019-12-09 10:25:54 +01:00
|
|
|
os.system("cp usb3_core/daisho/usb3/*.init build/gateware/")
|
2019-10-07 12:49:11 +02:00
|
|
|
platform = Platform()
|
|
|
|
soc = USB3SoC(platform)
|
2019-10-07 23:30:54 +02:00
|
|
|
builder = Builder(soc, output_dir="build", csr_csv="tools/csr.csv")
|
2019-10-07 12:49:11 +02:00
|
|
|
vns = builder.build()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|