diff --git a/litex_boards/platforms/efinix_t8f81_dev_kit.py b/litex_boards/platforms/efinix_t8f81_dev_kit.py new file mode 100644 index 0000000..870d445 --- /dev/null +++ b/litex_boards/platforms/efinix_t8f81_dev_kit.py @@ -0,0 +1,65 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Andrew Dennison +# Copyright (c) 2022 Charles-Henri Mousset +# SPDX-License-Identifier: BSD-2-Clause + +import os +from litex.build.generic_platform import * +from litex.build.efinix.platform import EfinixPlatform +from litex.build.efinix.programmer import EfinixAtmelProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk + ("clk33", 0, Pins("C3"), IOStandard("3.3_V_LVTTL_/_LVCMOS")), # net PLL_IN + + # Buttons + ("user_btn", 0, Pins("G1"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("WEAK_PULLUP")), + ("user_btn", 1, Pins("F1"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("WEAK_PULLUP")), + + # Leds + ("user_led", 0, Pins("G4"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=3")), + ("user_led", 1, Pins("J2"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=3")), + ("user_led", 2, Pins("C2"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=3")), + ("user_led", 3, Pins("E3"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=3")), + ("user_led", 4, Pins("B3"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=3")), + + # SPIFlash (W25Q80DV) + ("spiflash", 0, + Subsignal("cs_n", Pins("J4")), # net SPI_SS + Subsignal("clk", Pins("H4")), # net SPI_SCLK + Subsignal("mosi", Pins("F4")), # net SPI_MOSI + Subsignal("miso", Pins("H3")), # net SPI_MISO + #Subsignal("wp", Pins("")), + #Subsignal("hold", Pins("")), + IOStandard("3.3_V_LVTTL_/_LVCMOS") + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + # use "j3:1" reference for pin 1 of J3. This makes it a 1:1 translation with connector numbering + ("j3", "ZERO #N/A #N/A G5 F1 G4 E1 J3 C2 G3 D2 J2 E3 H2 D3 F3 C3 G1 B3 #N/A #N/A A2 A2"), + ("j4", "ZERO #N/A #N/A A5 B8 B5 C8 C5 D6 A6 B9 B6 C9 C6 D7 C7 D8 A8 D9 A9 E8 A2 A2"), + ("j5", "ZERO #N/A #N/A F8 J9 E7 J8 F7 G8 E6 H8 F6 J7 F5 G6 G9 H6 H9 J6 #N/A #N/A A2 A2"), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(EfinixPlatform): + default_clk_name = "clk33" + default_clk_period = 1e9/33.333e6 + + def __init__(self, toolchain="efinity"): + EfinixPlatform.__init__(self, "T8F81C2", _io, _connectors, toolchain=toolchain) + + def create_programmer(self): + return EfinixAtmelProgrammer() + + def do_finalize(self, fragment): + EfinixPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk33", loose=True), 1e9/33.333e6) diff --git a/litex_boards/targets/efinix_t8f81_dev_kit.py b/litex_boards/targets/efinix_t8f81_dev_kit.py new file mode 100755 index 0000000..ef94844 --- /dev/null +++ b/litex_boards/targets/efinix_t8f81_dev_kit.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Andrew Dennison +# Copyright (c) 2021 Franck Jullien +# Copyright (c) 2021 Florent Kermarrec +# Copyright (c) 2022 Charles-Henri Mousset +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex_boards.platforms import efinix_t8f81_dev_kit + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser + +kB = 1024 +mB = 1024*kB + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + + # # # + + clk33 = platform.request("clk33") + rst_n = platform.request("user_btn", 0) + + # PLL. + self.submodules.pll = pll = TRIONPLL(platform) + self.comb += pll.reset.eq(~rst_n) + pll.register_clkin(clk33, 33.333e6) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=True) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, bios_flash_offset, sys_clk_freq, with_led_chaser=True, **kwargs): + platform = efinix_t8f81_dev_kit.Platform() + + # Disable Integrated ROM. + kwargs["integrated_rom_size"] = 0 + + # Set CPU variant / reset address + if kwargs.get("cpu_type", "vexriscv") == "vexriscv": + kwargs["cpu_variant"] = "minimal" + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Efinix T8F81 Dev Kit", + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SPI Flash -------------------------------------------------------------------------------- + from litespi.modules import W25Q80BV + from litespi.opcodes import SpiNorFlashOpCodes as Codes + self.add_spi_flash(mode="1x", module=W25Q80BV(Codes.READ_1_1_1), with_master=False) + + # Add ROM linker region -------------------------------------------------------------------- + self.bus.add_region("rom", SoCRegion( + origin = self.bus.regions["spiflash"].origin + bios_flash_offset, + size = 32*kB, + linker = True) + ) + self.cpu.set_reset_address(self.bus.regions["rom"].origin) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + + +def main(): + from litex.soc.integration.soc import LiteXSoCArgumentParser + parser = LiteXSoCArgumentParser(description="LiteX SoC on Efinix T8F81C Dev Kit") + target_group = parser.add_argument_group(title="Target options") + target_group.add_argument("--build", action="store_true", help="Build bitstream.") + target_group.add_argument("--load", action="store_true", help="Load bitstream.") + target_group.add_argument("--flash", action="store_true", help="Flash Bitstream.") + target_group.add_argument("--sys-clk-freq", default=33.333e6, help="System clock frequency.") + target_group.add_argument("--bios-flash-offset", default="0x40000", help="BIOS offset in SPI Flash.") + + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + bios_flash_offset = int(args.bios_flash_offset, 0), + sys_clk_freq = int(float(args.sys_clk_freq)), + **soc_core_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build(run=args.build) + + if args.load: + prog = soc.platform.create_programmer() + prog.add_hex(0, builder.get_bitstream_filename(mode="sram")) + prog.load() + + if args.flash: + prog = soc.platform.create_programmer() + prog.add_hex(0, builder.get_bitstream_filename(mode="sram")) + prog.add_bin(int(args.bios_flash_offset, 0), builder.get_bios_filename()) + prog.flash() + +if __name__ == "__main__": + main()