diff --git a/litex_boards/platforms/jungle_electronics_fireant.py b/litex_boards/platforms/jungle_electronics_fireant.py new file mode 100644 index 0000000..e6015f5 --- /dev/null +++ b/litex_boards/platforms/jungle_electronics_fireant.py @@ -0,0 +1,62 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Miodrag Milanovic +# SPDX-License-Identifier: BSD-2-Clause + +# Board schematics at: +# https://github.com/jungle-elec/FireAnt + + +from litex.build.generic_platform import * +from litex.build.efinix.platform import EfinixPlatform +from litex.build.openfpgaloader import OpenFPGALoader + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk + ("clk33", 0, Pins("C3"), IOStandard("3.3_V_LVTTL_/_LVCMOS")), + + # Leds + ("user_led", 0, Pins("C5"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=1")), + ("user_led", 1, Pins("B6"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=1")), + ("user_led", 2, Pins("C7"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=1")), + ("user_led", 3, Pins("A9"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("DRIVE_STRENGTH=1")), + + # Buttons + ("user_btn", 0, Pins("J9"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("WEAK_PULLUP")), + ("user_btn", 1, Pins("J8"), IOStandard("3.3_V_LVTTL_/_LVCMOS"), Misc("WEAK_PULLUP")), + + # SPIFlash + ("spiflash", 0, + Subsignal("cs_n", Pins("J4")), + Subsignal("clk", Pins("H4")), + Subsignal("mosi", Pins("F4")), + Subsignal("miso", Pins("H3")), + IOStandard("3.3_V_LVTTL_/_LVCMOS") + ), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ["J1", " - G5 G4 J3 G3 J2 H2 F3 G1 F1 E2 E1 C2 D2 E3 D3 B3 A5 B5 -"], + ["J2", " - - H8 G8 H9 G9 F5 F6 F7 E7 F8 E8 D9 B9 C8 B8 A8 C6 A6 -"], +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(EfinixPlatform): + default_clk_name = "clk33" + default_clk_period = 1e9/33.33e6 + + def __init__(self): + EfinixPlatform.__init__(self, "T8F81C2", _io, _connectors, toolchain="efinity") + + def create_programmer(self): + return OpenFPGALoader("fireant") + + def do_finalize(self, fragment): + EfinixPlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk33", loose=True), 1e9/33.33e6) diff --git a/litex_boards/targets/jungle_electronics_fireant.py b/litex_boards/targets/jungle_electronics_fireant.py new file mode 100755 index 0000000..a197fed --- /dev/null +++ b/litex_boards/targets/jungle_electronics_fireant.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Miodrag Milanovic +# Copyright (c) 2021 Andrew Dennison +# Copyright (c) 2021 Franck Jullien +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex_boards.platforms import jungle_electronics_fireant + +from litex.build.generic_platform import * + +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) + +# Default peripherals +serial = [ + ("serial", 0, + Subsignal("tx", Pins("J2:2")), + Subsignal("rx", Pins("J2:3")), + IOStandard("3.3_V_LVTTL_/_LVCMOS") , Misc("WEAK_PULLUP") + ) +] + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + mem_map = {**SoCCore.mem_map, **{"spiflash": 0x80000000}} + def __init__(self, bios_flash_offset, sys_clk_freq, with_led_chaser=True, **kwargs): + platform = jungle_electronics_fireant.Platform() + platform.add_extension(serial) + + # Disable Integrated ROM since too large for this device. + kwargs["integrated_rom_size"] = 0 + + # Set CPU variant / reset address + if kwargs.get("cpu_type", "vexriscv") == "vexriscv": + kwargs["cpu_variant"] = "minimal" + kwargs["cpu_reset_address"] = self.mem_map["spiflash"] + bios_flash_offset + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Jungle Electronics FireAnt", + ident_version = True, + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # SPI Flash -------------------------------------------------------------------------------- + from litespi.modules import W25Q80BV + from litespi.opcodes import SpiNorFlashOpCodes as Codes + # Board is using W25Q80DV, which is replacemenet for W25Q80BV + 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.mem_map["spiflash"] + bios_flash_offset, + size = 32*kB, + linker = True) + ) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Jungle Electronics FireAnt") + 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=33.333e6, help="System clock frequency (default: 33.333MHz)") + parser.add_argument("--bios-flash-offset", default=0x40000, help="BIOS offset in SPI Flash (default: 0x40000)") + + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + bios_flash_offset = args.bios_flash_offset, + 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.load_bitstream(os.path.join(builder.gateware_dir, f"{soc.build_name}.hex")) + + if args.flash: + prog = soc.platform.create_programmer() + prog.flash(0, os.path.join(builder.gateware_dir, f"{soc.build_name}.hex")) + prog.flash(args.bios_flash_offset, os.path.join(builder.software_dir, "bios/bios.bin")) + +if __name__ == "__main__": + main() diff --git a/test/test_targets.py b/test/test_targets.py index bfb7dd1..0b25e00 100644 --- a/test/test_targets.py +++ b/test/test_targets.py @@ -22,6 +22,7 @@ class TestTargets(unittest.TestCase): "efinix_trion_t20_mipi_dev_kit", # Reason: Require Efinity toolchain. "efinix_xyloni_dev_kit", # Reason: Require Efinity toolchain. "sipeed_tang_primer", # Reason: Require Anlogic toolchain. + "jungle_electronics_fireant", # Reason: Require Efinity toolchain. ] excluded_targets = [ "simple", # Reason: Generic target. @@ -31,6 +32,7 @@ class TestTargets(unittest.TestCase): "efinix_trion_t20_mipi_dev_kit", # Reason: Require Efinity toolchain. "efinix_xyloni_dev_kit", # Reason: Require Efinity toolchain. "sipeed_tang_primer", # Reason: Require Anlogic toolchain. + "jungle_electronics_fireant", # Reason: Require Efinity toolchain. ] # Build simple design for all platforms.