From e84f32b9188f0e2041ecc32f7b26075322e44b9e Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Fri, 10 Dec 2021 23:38:55 +0100 Subject: [PATCH] efinix: add titanium Ti60 dev kit --- .../efinix_titanium_ti60_bga225_dev_kit.py | 115 ++++++++++++++++++ .../efinix_titanium_ti60_bga225_dev_kit.py | 97 +++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 litex_boards/platforms/efinix_titanium_ti60_bga225_dev_kit.py create mode 100755 litex_boards/targets/efinix_titanium_ti60_bga225_dev_kit.py diff --git a/litex_boards/platforms/efinix_titanium_ti60_bga225_dev_kit.py b/litex_boards/platforms/efinix_titanium_ti60_bga225_dev_kit.py new file mode 100644 index 0000000..2b2b0cc --- /dev/null +++ b/litex_boards/platforms/efinix_titanium_ti60_bga225_dev_kit.py @@ -0,0 +1,115 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Franck Jullien +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.efinix.platform import EfinixPlatform +from litex.build.efinix import EfinixProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk + ("clk25", 0, Pins("B2"), IOStandard("1.8_V_LVCMOS")), + ("clk33", 0, Pins("P2"), IOStandard("1.8_V_LVCMOS")), + ("clk74_25", 0, Pins("A11"), IOStandard("1.8_V_LVCMOS")), + + # SD-Card + ("sdcard", 0, + Subsignal("data", Pins("B14 A14 D12 A12")), + Subsignal("cmd", Pins("C12")), + Subsignal("clk", Pins("B12")), + IOStandard("3.3_V_LVCMOS"), + ), + + # Serial + ("serial", 0, + Subsignal("tx", Pins("R4")), + Subsignal("rx", Pins("R3")), + IOStandard("3.3_V_LVCMOS"), Misc("WEAK_PULLUP") + ), + + # Leds + ("user_led", 0, + Subsignal("r", Pins("J15")), + Subsignal("g", Pins("H10")), + Subsignal("b", Pins("K14")), + IOStandard("1.8_V_LVCMOS"), + ), + ("user_led", 1, + Subsignal("r", Pins("H15")), + Subsignal("g", Pins("H11")), + Subsignal("b", Pins("J14")), + IOStandard("1.8_V_LVCMOS"), + ), + + # Buttons + ("user_btn", 0, Pins("K13"), IOStandard("1.8_V_LVCMOS")), + ("user_btn", 1, Pins("J13"), IOStandard("1.8_V_LVCMOS")), + ("user_btn", 2, Pins("C5"), IOStandard("1.8_V_LVCMOS")), + ("user_btn", 3, Pins("R13"), IOStandard("1.8_V_LVCMOS")), + + # Switches + ("user_sw", 0, Pins("F3"), IOStandard("1.8_V_LVCMOS")), + ("user_sw", 1, Pins("E3"), IOStandard("1.8_V_LVCMOS")), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("P1")), + Subsignal("clk", Pins("N1")), + Subsignal("mosi", Pins("M1")), + Subsignal("miso", Pins("L1")), + IOStandard("1.8_V_LVCMOS") + ), + + # HyperRAM + ("hyperram", 0, + Subsignal("dq", Pins("B6 C6 A5 A6 F7 F8 E7 D7 B9 A9 F9 E9 C10 D10 A10 B10"), IOStandard("1.8_V_LVCMOS")), + Subsignal("rwds", Pins("B8 C8"), IOStandard("1.8_V_LVCMOS")), + Subsignal("cs_n", Pins("A8"), IOStandard("1.8_V_LVCMOS")), + Subsignal("rst_n", Pins("D5"), IOStandard("1.8_V_LVCMOS")), + Subsignal("clk", Pins("B7"), IOStandard("LVDS")), + # Subsignal("clk_n", Pins("T7"), IOStandard("LVDS")), + Misc("SLEWRATE=FAST") + ), +] + +iobank_info = [ + ("1A", "1.8 V LVCMOS"), + ("1B", "1.8 V LVCMOS"), + ("2A", "1.8 V LVCMOS"), + ("2B", "1.8 V LVCMOS"), + ("3A", "1.8 V LVCMOS"), + ("3B", "1.8 V LVCMOS"), + ("4A", "1.8 V LVCMOS"), + ("4B", "1.8 V LVCMOS"), + ("BL", "3.3 V LVCMOS"), + ("BR", "1.8 V LVCMOS"), + ("TL", "1.8 V LVCMOS"), + ("TR", "3.3 V LVCMOS"), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ["P1", " - H14 - G14 - - F12 G13 E12 F13 - - E15 H13 E14 H12 - - C13 G15 D13 F15", + " - - D15 G11 D14 F11 - - C14 N14 C15 P14 - - K4 A4 J3 B5"], +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(EfinixPlatform): + default_clk_name = "clk25" + default_clk_period = 1e9/50e6 + + def __init__(self): + EfinixPlatform.__init__(self, "Ti60F225C3", _io, _connectors, iobank_info=iobank_info, toolchain="efinity") + + def create_programmer(self): + return EfinixProgrammer() + + def do_finalize(self, fragment): + EfinixPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/50e6) diff --git a/litex_boards/targets/efinix_titanium_ti60_bga225_dev_kit.py b/litex_boards/targets/efinix_titanium_ti60_bga225_dev_kit.py new file mode 100755 index 0000000..10bdb28 --- /dev/null +++ b/litex_boards/targets/efinix_titanium_ti60_bga225_dev_kit.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Franck Jullien +# SPDX-License-Identifier: BSD-2-Clause + +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex_boards.platforms import efinix_titanium_ti60_bga225_dev_kit + +from litex.build.generic_platform import * + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + + # # # + + clk25 = platform.request("clk25") + rst_n = platform.request("user_btn", 0) + + # PLL + self.submodules.pll = pll = TITANIUMPLL(platform) + self.comb += pll.reset.eq(~rst_n) + pll.register_clkin(clk25, 25e6) + # You can use CLKOUT0 only for clocks with a maximum frequency of 4x + # (integer) of the reference clock. If all your system clocks do not fall within + # this range, you should dedicate one unused clock for CLKOUT0. + pll.create_clkout(None, 25e6) + + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(50e6), with_spi_flash=False, with_led_chaser=False, **kwargs): + platform = efinix_titanium_ti60_bga225_dev_kit.Platform() + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Efinix Titanium Ti60 BGA225 Dev Kit", + ident_version = True, + **kwargs + ) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SPI Flash -------------------------------------------------------------------------------- + if with_spi_flash: + from litespi.modules import W25Q32JV + from litespi.opcodes import SpiNorFlashOpCodes as Codes + self.add_spi_flash(mode="1x", module=W25Q32JV(Codes.READ_1_1_1), with_master=True) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Efinix Trion T20 BGA256 Dev Kit") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--load", action="store_true", help="Load bitstream") + parser.add_argument("--flash", action="store_true", help="Flash bitstream") + parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default: 100MHz)") + parser.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed)") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = int(float(args.sys_clk_freq)), + with_spi_flash = args.with_spi_flash, + **soc_core_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build(run=args.build) + + if args.load: + prog = soc.platform.create_programmer() + prog.load_bitstream(os.path.join(builder.gateware_dir, f"{soc.build_name}.bit")) + + if args.flash: + from litex.build.openfpgaloader import OpenFPGALoader + prog = OpenFPGALoader("titanium_ti60_bga225") + prog.flash(0, os.path.join(builder.gateware_dir, f"{soc.build_name}.hex")) + +if __name__ == "__main__": + main()