diff --git a/litex_boards/platforms/gsd_butterstick.py b/litex_boards/platforms/gsd_butterstick.py new file mode 100644 index 0000000..8564147 --- /dev/null +++ b/litex_boards/platforms/gsd_butterstick.py @@ -0,0 +1,55 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Greg Davill +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import OpenOCDJTAGProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io_r1_0 = [ + # Clk + ("clk30", 0, Pins("B12"), IOStandard("LVCMOS33")), + + # Leds + ("user_led", 0, Pins("C13"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("D12"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins(" U2"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins(" T3"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("D13"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("E13"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("C16"), IOStandard("LVCMOS33")), + ("user_led_color", 0, Pins("T1 R1 U1"), IOStandard("LVCMOS33")), + + # Buttons + ("user_btn", 0, Pins("U16"), IOStandard("SSTL135_I")), + ("user_btn", 1, Pins("T17"), IOStandard("SSTL135_I")), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors_r1_0 = [] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticePlatform): + default_clk_name = "clk30" + default_clk_period = 1e9/30e6 + + def __init__(self, revision="1.0", device="85F", toolchain="trellis", **kwargs): + assert revision in ["1.0"] + self.revision = revision + io = {"1.0": _io_r1_0}[revision] + connectors = {"1.0": _connectors_r1_0}[revision] + LatticePlatform.__init__(self, f"LFE5UM5G-{device}-8BG381C", io, connectors, toolchain=toolchain, **kwargs) + + def create_programmer(self): + return OpenOCDJTAGProgrammer("openocd_butterstick.cfg") + + def do_finalize(self, fragment): + LatticePlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk30", loose=True), 1e9/30e6) diff --git a/litex_boards/prog/openocd_butterstick.cfg b/litex_boards/prog/openocd_butterstick.cfg new file mode 100644 index 0000000..88d49cf --- /dev/null +++ b/litex_boards/prog/openocd_butterstick.cfg @@ -0,0 +1,9 @@ +interface ftdi +ftdi_vid_pid 0x0403 0x6014 +ftdi_channel 0 +ftdi_layout_init 0x00e8 0x60eb +reset_config none + +adapter_khz 25000 + +jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043 diff --git a/litex_boards/targets/gsd_butterstick.py b/litex_boards/targets/gsd_butterstick.py new file mode 100755 index 0000000..cf56be0 --- /dev/null +++ b/litex_boards/targets/gsd_butterstick.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Florent Kermarrec +# Copyright (c) 2021 Greg Davill +# SPDX-License-Identifier: BSD-2-Clause + +import os +import sys +import argparse + +from migen import * +from litex_boards.platforms import butterstick + +from litex.build.lattice.trellis import trellis_args, trellis_argdict + +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.rst = Signal() + self.clock_domains.cd_por = ClockDomain(reset_less=True) + self.clock_domains.cd_sys = ClockDomain() + + # # # + + # Clk / Rst + clk30 = platform.request("clk30") + rst_n = platform.request("user_btn", 0) + + # Power on reset + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += self.cd_por.clk.eq(clk30) + self.comb += por_done.eq(por_count == 0) + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + + # PLL + self.submodules.pll = pll = ECP5PLL() + self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst) + pll.register_clkin(clk30, 30e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, revision="1.0", device="25F", sys_clk_freq=int(60e6), toolchain="trellis", with_led_chaser=True, **kwargs): + platform = butterstick.Platform(revision=revision, device=device ,toolchain=toolchain) + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on ButterStick", + ident_version = True, + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.comb += platform.request("user_led_color").eq(0b010) # Blue. + 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 ButterStick") + parser.add_argument("--build", action="store_true", help="Build bitstream") + parser.add_argument("--load", action="store_true", help="Load bitstream") + parser.add_argument("--toolchain", default="trellis", help="FPGA use, trellis (default) or diamond") + parser.add_argument("--sys-clk-freq", default=60e6, help="System clock frequency (default: 60MHz)") + parser.add_argument("--revision", default="1.0", help="Board Revision: 1.0 (default)") + parser.add_argument("--device", default="85F", help="ECP5 device (default: 85F)") + builder_args(parser) + soc_core_args(parser) + trellis_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + toolchain = args.toolchain, + revision = args.revision, + device = args.device, + sys_clk_freq = int(float(args.sys_clk_freq)), + **soc_core_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {} + builder.build(**builder_kargs, 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()