diff --git a/acorn.py b/acorn.py new file mode 100755 index 0000000..f1cf751 --- /dev/null +++ b/acorn.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 + +# +# This file is part of USB3-PIPE project. +# +# Copyright (c) 2019-2022 Florent Kermarrec +# 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="tools/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="tools/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()