From c7444fe19cb7fcf9758bce67a04b85f198776ec0 Mon Sep 17 00:00:00 2001 From: DurandA Date: Mon, 5 Aug 2019 14:34:56 +0200 Subject: [PATCH] Add ECP5 Evaluation Board --- MANIFEST.in | 1 + litex_boards/community/platforms/ecp5_evn.py | 136 ++++++++++++++++++ .../community/platforms/prog/ecp5-evn.cfg | 16 +++ litex_boards/community/targets/ecp5_evn.py | 72 ++++++++++ 4 files changed, 225 insertions(+) create mode 100644 MANIFEST.in create mode 100644 litex_boards/community/platforms/ecp5_evn.py create mode 100644 litex_boards/community/platforms/prog/ecp5-evn.cfg create mode 100755 litex_boards/community/targets/ecp5_evn.py diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..382c984 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +graft litex_boards/community/platforms/prog diff --git a/litex_boards/community/platforms/ecp5_evn.py b/litex_boards/community/platforms/ecp5_evn.py new file mode 100644 index 0000000..ddf5cdc --- /dev/null +++ b/litex_boards/community/platforms/ecp5_evn.py @@ -0,0 +1,136 @@ +# This file is Copyright (c) 2019 Arnaud Durand +# License: BSD + +import warnings + +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import LatticeProgrammer +from litex.build.openocd import OpenOCD + +# IOs ---------------------------------------------------------------------------------------------- + +_io = [ + ("clk12", 0, Pins("A10"), IOStandard("LVCMOS33")), + ("rst_n", 0, Pins("G2"), IOStandard("LVCMOS33")), + + ("user_led", 0, Pins("A13"), IOStandard("LVCMOS25")), + ("user_led", 1, Pins("A12"), IOStandard("LVCMOS25")), + ("user_led", 2, Pins("B19"), IOStandard("LVCMOS25")), + ("user_led", 3, Pins("A18"), IOStandard("LVCMOS25")), + ("user_led", 4, Pins("B18"), IOStandard("LVCMOS25")), + ("user_led", 5, Pins("C17"), IOStandard("LVCMOS25")), + ("user_led", 6, Pins("A17"), IOStandard("LVCMOS25")), + ("user_led", 7, Pins("B17"), IOStandard("LVCMOS25")), + + ("user_dip_btn", 1, Pins("J1"), IOStandard("LVCMOS33")), + ("user_dip_btn", 2, Pins("H1"), IOStandard("LVCMOS33")), + ("user_dip_btn", 3, Pins("K1"), IOStandard("LVCMOS33")), + ("user_dip_btn", 4, Pins("E15"), IOStandard("LVCMOS25")), + ("user_dip_btn", 5, Pins("D16"), IOStandard("LVCMOS25")), + ("user_dip_btn", 6, Pins("B16"), IOStandard("LVCMOS25")), + ("user_dip_btn", 7, Pins("C16"), IOStandard("LVCMOS25")), + ("user_dip_btn", 8, Pins("A16"), IOStandard("LVCMOS25")), + + ("serial", 0, + Subsignal("rx", Pins("P18"), IOStandard("LVCMOS33")), + Subsignal("tx", Pins("N20"), IOStandard("LVCMOS33")), + ), + ("serial", 1, + Subsignal("rx", Pins("P2"), IOStandard("LVCMOS33")), + Subsignal("tx", Pins("P3"), IOStandard("LVCMOS33")), + ), + + ("clk200", 0, + Subsignal("p", Pins("Y19")), + Subsignal("n", Pins("W20")), + IOStandard("LVDS") + ), + ("ext_clk50", 0, Pins("B11"), IOStandard("LVCMOS33")), +] + +# Connectors --------------------------------------------------------------------------------------- + +_connectors = [ + ("RASP", + "None", # (no pin 0) + "None", # 1 3.3V + "None", # 2 5V + "T17", # 3 RASP_IO02 + "None", # 4 5V + "U16", # 5 RASP_IO03 + "None", # 6 GND + "U17", # 7 RASP_IO04 + "P18", # 8 RASP_IO14 + "None", # 9 GND + "N20", # 10 RASP_IO15 + "N19", # 11 RASP_IO17 + "T16", # 12 RASP_IO18 + "M18", # 13 RASP_IO27 + "None", # 14 GND + "N17", # 15 RASP_IO22 + "P17", # 16 RASP_IO23 + "None", # 17 3.3V + "M17", # 18 RASP_IO24 + "U20", # 19 RASP_IO10 + "None", # 20 GND + "T19", # 21 RASP_IO09 + "N18", # 22 RASP_IO25 + "R20", # 23 RASP_IO11 + "U19", # 24 RASP_IO08 + "None", # 25 GND + "R18", # 26 RASP_IO07 + "L18", # 27 RASP_ID_SD + "L17", # 28 RASP_ID_SC + "U18", # 29 RASP_IO05 + "None", # 30 GND + "T18", # 31 RASP_IO06 + "T20", # 32 RASP_IO12 + "P20", # 33 RASP_IO13 + "None", # 34 GND + "R17", # 35 RASP_IO19 + "P19", # 36 RASP_IO16 + "N16", # 37 RASP_IO26 + "P16", # 38 RASP_IO20 + "None", # 39 GND + "R16", # 40 RASP_IO21 + ), + + ("PMOD", + "None", # (no pin 0) + "C6", # 1 + "C7", # 2 + "E8", # 3 + "D8", # 4 + "None", # 5 GND + "None", # 6 VCCIO0 + "C8", # 7 EXPCON_IO32 + "B8", # 8 EXPCON_IO33 + "A7", # 9 EXPCON_IO34 + "A8", # 10 EXPCON_IO35 + "None", # 11 GND + "None", # 12 VCCIO0 + ), +] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticePlatform): + default_clk_name = "clk12" + default_clk_period = 83.33 + + def __init__(self, **kwargs): + LatticePlatform.__init__(self, "LFE5UM5G-85F-8BG381", _io, _connectors, **kwargs) + + def request(self, *args, **kwargs): + if "serial" in args: + warnings.warn("two 0 Ω resistors shoud be populated on R34 and R35") + if "ext_clk50" in args: + warnings.warn("an oscillator must be populated on X5") + + return LatticePlatform.request(self, *args, **kwargs) + + def create_programmer(self): + fdir = os.path.join( + os.path.abspath(os.path.dirname(__file__)), "prog") + return OpenOCD(os.path.join(fdir, "ecp5-evn.cfg")) \ No newline at end of file diff --git a/litex_boards/community/platforms/prog/ecp5-evn.cfg b/litex_boards/community/platforms/prog/ecp5-evn.cfg new file mode 100644 index 0000000..8828b92 --- /dev/null +++ b/litex_boards/community/platforms/prog/ecp5-evn.cfg @@ -0,0 +1,16 @@ +# this supports ECP5 Evaluation Board + +interface ftdi +ftdi_device_desc "Lattice ECP5 Evaluation Board" +ftdi_vid_pid 0x0403 0x6010 +# channel 1 does not have any functionality +ftdi_channel 0 +# just TCK TDI TDO TMS, no reset +ftdi_layout_init 0xfff8 0xfffb +reset_config none + +# default speed +adapter_khz 5000 + +# ECP5 device - LFE5UM5G-85F +jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043 diff --git a/litex_boards/community/targets/ecp5_evn.py b/litex_boards/community/targets/ecp5_evn.py new file mode 100755 index 0000000..f548627 --- /dev/null +++ b/litex_boards/community/targets/ecp5_evn.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +# This file is Copyright (c) 2019 Arnaud Durand +# License: BSD + +import argparse +from warnings import warn + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex_boards.community.platforms import ecp5_evn + +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.clock_domains.cd_sys = ClockDomain() + + # # # + + self.cd_sys.clk.attr.add("keep") + + # clk / rst + clk12 = platform.request("clk12") + rst_n = platform.request("rst_n") + platform.add_period_constraint(clk12, 83.33) + + # pll + # self.submodules.pll = pll = ECP5PLL() + # self.comb += pll.reset.eq(~rst_n) + # pll.register_clkin(clk12, 12e6) + # pll.create_clkout(self.cd_sys, sys_clk_freq) + # self.specials += AsyncResetSynchronizer(self.cd_sys, ~rst_n) + self.comb += self.cd_sys.clk.eq(clk12) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCCore): + def __init__(self, sys_clk_freq=int(12e6), toolchain="diamond", **kwargs): + platform = ecp5_evn.Platform(toolchain=toolchain) + SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, + integrated_rom_size=0x8000, + **kwargs) + + # crg + crg = _CRG(platform, sys_clk_freq) + self.submodules.crg = crg + +# Build -------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on ECP5 Evaluation Board") + parser.add_argument("--gateware-toolchain", dest="toolchain", default="diamond", + help='gateware toolchain to use, diamond (default) or trellis') + builder_args(parser) + soc_core_args(parser) + parser.add_argument("--sys-clk-freq", default=12e6, + help="system clock frequency (default=50MHz)") + args = parser.parse_args() + + cls = BaseSoC + soc = cls(toolchain=args.toolchain, sys_clk_freq=int(float(args.sys_clk_freq)), **soc_core_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build() + +if __name__ == "__main__": + main()