From c7444fe19cb7fcf9758bce67a04b85f198776ec0 Mon Sep 17 00:00:00 2001 From: DurandA Date: Mon, 5 Aug 2019 14:34:56 +0200 Subject: [PATCH 1/4] 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() From 4126ed21d5ef1c904b2ef3268e2cd40e0a7799fa Mon Sep 17 00:00:00 2001 From: DurandA Date: Fri, 9 Aug 2019 09:42:17 +0200 Subject: [PATCH 2/4] Add X5 clock and PLL to ECP5 Evaluation Board --- litex_boards/community/platforms/ecp5_evn.py | 15 ++++---- litex_boards/community/targets/ecp5_evn.py | 36 ++++++++++++-------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/litex_boards/community/platforms/ecp5_evn.py b/litex_boards/community/platforms/ecp5_evn.py index ddf5cdc..61db93d 100644 --- a/litex_boards/community/platforms/ecp5_evn.py +++ b/litex_boards/community/platforms/ecp5_evn.py @@ -1,8 +1,6 @@ # 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 @@ -33,10 +31,6 @@ _io = [ ("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")), ), @@ -47,6 +41,7 @@ _io = [ IOStandard("LVDS") ), ("ext_clk50", 0, Pins("B11"), IOStandard("LVCMOS33")), + ("ext_clk50_en", 0, Pins("C11"), IOStandard("LVCMOS33")), ] # Connectors --------------------------------------------------------------------------------------- @@ -117,16 +112,18 @@ _connectors = [ class Platform(LatticePlatform): default_clk_name = "clk12" - default_clk_period = 83.33 + default_clk_period = 1e9/12e6 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") + print("two 0 Ω resistors shoud be populated on R34 and R35 and " + "the FT2232H should be configured to UART with virtual COM on " + "port B") if "ext_clk50" in args: - warnings.warn("an oscillator must be populated on X5") + print("an oscillator must be populated on X5") return LatticePlatform.request(self, *args, **kwargs) diff --git a/litex_boards/community/targets/ecp5_evn.py b/litex_boards/community/targets/ecp5_evn.py index f548627..bd365b4 100755 --- a/litex_boards/community/targets/ecp5_evn.py +++ b/litex_boards/community/targets/ecp5_evn.py @@ -4,7 +4,6 @@ # License: BSD import argparse -from warnings import warn from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer @@ -18,7 +17,7 @@ from litex.soc.integration.builder import * # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): - def __init__(self, platform, sys_clk_freq): + def __init__(self, platform, sys_clk_freq, x5_clk_freq): self.clock_domains.cd_sys = ClockDomain() # # # @@ -26,29 +25,33 @@ class _CRG(Module): self.cd_sys.clk.attr.add("keep") # clk / rst - clk12 = platform.request("clk12") + clk = clk12 = platform.request("clk12") rst_n = platform.request("rst_n") - platform.add_period_constraint(clk12, 83.33) + platform.add_period_constraint(clk12, 1e9/12e6) + if x5_clk_freq is not None: + clk = clk50 = platform.request("ext_clk50") + self.comb += platform.request("ext_clk50_en").eq(1) + platform.add_period_constraint(clk50, 1e9/x5_clk_freq) # 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) + self.submodules.pll = pll = ECP5PLL() + self.comb += pll.reset.eq(~rst_n) + pll.register_clkin(clk, x5_clk_freq or 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(clk) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, sys_clk_freq=int(12e6), toolchain="diamond", **kwargs): + def __init__(self, sys_clk_freq=int(50e6), x5_clk_freq=None, 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) + crg = _CRG(platform, sys_clk_freq, x5_clk_freq) self.submodules.crg = crg # Build -------------------------------------------------------------------------------------------- @@ -59,12 +62,17 @@ def main(): help='gateware toolchain to use, diamond (default) or trellis') builder_args(parser) soc_core_args(parser) - parser.add_argument("--sys-clk-freq", default=12e6, + parser.add_argument("--sys-clk-freq", default=50e6, help="system clock frequency (default=50MHz)") + parser.add_argument("--x5-clk-freq", type=int, + help="use X5 oscillator as system clock at the specified frequency") args = parser.parse_args() cls = BaseSoC - soc = cls(toolchain=args.toolchain, sys_clk_freq=int(float(args.sys_clk_freq)), **soc_core_argdict(args)) + soc = cls(toolchain=args.toolchain, + sys_clk_freq=int(float(args.sys_clk_freq)), + x5_clk_freq=args.x5_clk_freq, + **soc_core_argdict(args)) builder = Builder(soc, **builder_argdict(args)) builder.build() From 9e6dccc2776127308c92a9b109114e387a9352ef Mon Sep 17 00:00:00 2001 From: DurandA Date: Fri, 9 Aug 2019 09:48:43 +0200 Subject: [PATCH 3/4] Remove ECP5 Evaluation Board programmer --- MANIFEST.in | 1 - litex_boards/community/platforms/ecp5_evn.py | 9 ++++----- .../community/platforms/prog/ecp5-evn.cfg | 16 ---------------- 3 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 litex_boards/community/platforms/prog/ecp5-evn.cfg diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 382c984..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -graft litex_boards/community/platforms/prog diff --git a/litex_boards/community/platforms/ecp5_evn.py b/litex_boards/community/platforms/ecp5_evn.py index 61db93d..c7facfe 100644 --- a/litex_boards/community/platforms/ecp5_evn.py +++ b/litex_boards/community/platforms/ecp5_evn.py @@ -3,8 +3,6 @@ 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 ---------------------------------------------------------------------------------------------- @@ -128,6 +126,7 @@ class Platform(LatticePlatform): 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 + pass + # fdir = os.path.join( + # os.path.abspath(os.path.dirname(__file__)), "prog") + # return OpenOCD(os.path.join(fdir, "ecp5-evn.cfg")) diff --git a/litex_boards/community/platforms/prog/ecp5-evn.cfg b/litex_boards/community/platforms/prog/ecp5-evn.cfg deleted file mode 100644 index 8828b92..0000000 --- a/litex_boards/community/platforms/prog/ecp5-evn.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# 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 From c90950e3196d208dd688a73ba85946686948fbe8 Mon Sep 17 00:00:00 2001 From: DurandA Date: Fri, 9 Aug 2019 11:57:39 +0200 Subject: [PATCH 4/4] Default to 60 Mhz system clock on ECP5 Evaluation Board Exact PLL clock can be derived from U1 12 Mhz or X5 50 Mhz clock. --- litex_boards/community/targets/ecp5_evn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/litex_boards/community/targets/ecp5_evn.py b/litex_boards/community/targets/ecp5_evn.py index bd365b4..3b1a766 100755 --- a/litex_boards/community/targets/ecp5_evn.py +++ b/litex_boards/community/targets/ecp5_evn.py @@ -62,8 +62,8 @@ def main(): help='gateware toolchain to use, diamond (default) or trellis') builder_args(parser) soc_core_args(parser) - parser.add_argument("--sys-clk-freq", default=50e6, - help="system clock frequency (default=50MHz)") + parser.add_argument("--sys-clk-freq", default=60e6, + help="system clock frequency (default=60MHz)") parser.add_argument("--x5-clk-freq", type=int, help="use X5 oscillator as system clock at the specified frequency") args = parser.parse_args()