From 3ad0eb6992e13f6fd4758044ec2eb03a107e0d6f Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 16 Sep 2021 17:44:09 +0200 Subject: [PATCH] Add initial LiteX M2 Baseboard support with Clk/Serial/Buttons. --- litex_boards/platforms/litex_m2_baseboard.py | 47 ++++++++++ litex_boards/targets/litex_m2_baseboard.py | 92 ++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 litex_boards/platforms/litex_m2_baseboard.py create mode 100755 litex_boards/targets/litex_m2_baseboard.py diff --git a/litex_boards/platforms/litex_m2_baseboard.py b/litex_boards/platforms/litex_m2_baseboard.py new file mode 100644 index 0000000..4fa5b1a --- /dev/null +++ b/litex_boards/platforms/litex_m2_baseboard.py @@ -0,0 +1,47 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Ilia Sergachev +# 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.openfpgaloader import OpenFPGALoader + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + # Clk / Rst + ("clk50", 0, Pins("L19"), IOStandard("LVCMOS33")), + + # Serial + ("serial", 0, + Subsignal("rx", Pins("B20"), IOStandard("LVCMOS33")), + Subsignal("tx", Pins("A19"), IOStandard("LVCMOS33")), + ), + + # Buttons + ("user_btn", 0, Pins("M19"), IOStandard("LVCMOS33")), + ("user_btn", 1, Pins("M20"), IOStandard("LVCMOS33")), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticePlatform): + default_clk_name = "clk50" + default_clk_period = 1e9/506 + + def __init__(self, toolchain="trellis", **kwargs): + LatticePlatform.__init__(self, "LFE5UM5G-45F-8BG381I", _io, _connectors, toolchain=toolchain, **kwargs) + + def create_programmer(self): + return OpenFPGALoader("ecpix5") + + def do_finalize(self, fragment): + LatticePlatform.do_finalize(self, fragment) + self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6) diff --git a/litex_boards/targets/litex_m2_baseboard.py b/litex_boards/targets/litex_m2_baseboard.py new file mode 100755 index 0000000..156b9ec --- /dev/null +++ b/litex_boards/targets/litex_m2_baseboard.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +import os +import argparse +import sys + +from migen import * + +from litex_boards.platforms import litex_m2_baseboard + +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 * + +# 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 + clk50 = platform.request("clk50") + + # Power on reset + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += self.cd_por.clk.eq(clk50) + 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 | self.rst) + pll.register_clkin(clk50, 50e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(75e6), **kwargs): + platform = litex_m2_baseboard.Platform(toolchain="trellis") + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on LiteX M2 Baseboard", + ident_version = True, + **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on LiteX M2 Baseboard") + 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 to SPI Flash") + parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default: 75MHz)") + builder_args(parser) + soc_core_args(parser) + trellis_args(parser) + args = parser.parse_args() + + soc = BaseSoC( + sys_clk_freq = int(float(args.sys_clk_freq)), + **soc_core_argdict(args) + ) + builder = Builder(soc, **builder_argdict(args)) + builder.build(**trellis_argdict(args), 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 args.flash: + prog = soc.platform.create_programmer() + prog.flash(None, os.path.join(builder.gateware_dir, soc.build_name + ".bit")) + +if __name__ == "__main__": + main()