usb3_pipe/acorn.py

165 lines
5.9 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
#
# This file is part of USB3-PIPE project.
#
# Copyright (c) 2019-2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import sys
from migen import *
from litex_boards.platforms import sqrl_acorn
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 litescope import LiteScopeAnalyzer
from usb3_pipe import A7USB3SerDes, USB3PIPE
from usb3_core.core import USB3Core
# USB3 IOs -----------------------------------------------------------------------------------------
_usb3_io = [
# SFP
("sfp_tx", 0,
Subsignal("p", Pins("D7")),
Subsignal("n", Pins("C7")),
),
("sfp_rx", 0,
Subsignal("p", Pins("D9")),
Subsignal("n", Pins("C9")),
),
]
# 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, with_analyzer=False):
sys_clk_freq = int(125e6)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# SoCMini ----------------------------------------------------------------------------------
SoCMini.__init__(self, platform, sys_clk_freq, ident="USB3SoC", ident_version=True)
# JTAGBone ---------------------------------------------------------------------------------
self.add_jtagbone()
# USB3 SerDes ------------------------------------------------------------------------------
usb3_serdes = A7USB3SerDes(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("sfp_tx"),
rx_pads = platform.request("sfp_rx"))
self.submodules += usb3_serdes
platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]")
# USB3 PIPE --------------------------------------------------------------------------------
usb3_pipe = USB3PIPE(serdes=usb3_serdes, sys_clk_freq=sys_clk_freq)
self.submodules.usb3_pipe = usb3_pipe
# 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),
]
# 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/sqrl_acorn/gateware", exist_ok=True)
os.system("cd usb3_core/daisho && make && ./usb_descrip_gen")
os.system("cp usb3_core/daisho/usb3/*.init build/sqrl_acorn/gateware/")
platform = sqrl_acorn.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()