diff --git a/litex_boards/platforms/radiona_ulx4m_ld_v2.py b/litex_boards/platforms/radiona_ulx4m_ld_v2.py index 84c2e59..3fb635f 100644 --- a/litex_boards/platforms/radiona_ulx4m_ld_v2.py +++ b/litex_boards/platforms/radiona_ulx4m_ld_v2.py @@ -1,27 +1,32 @@ # # This file is part of LiteX-Boards. # +# Copyright (c) 2022 Goran Mahovlic # Copyright (c) 2020 Greg Davill # SPDX-License-Identifier: BSD-2-Clause from litex.build.generic_platform import * -from litex.build.lattice import LatticePlatform +from litex.build.lattice import LatticeECP5Platform #from litex.build.dfu import DFUProg # IOs ---------------------------------------------------------------------------------------------- _io_r0_1 = [ + # Clk/Rst. ("clk25", 0, Pins("G2"), IOStandard("LVCMOS33")), ("rst_n", 0, Pins("F1"), IOStandard("LVCMOS33")), + # RGB Led. ("rgb_led", 0, Subsignal("r", Pins("A3"), IOStandard("LVCMOS33")), Subsignal("g", Pins("B3"), IOStandard("LVCMOS33")), Subsignal("b", Pins("B2"), IOStandard("LVCMOS33")), ), + # Buttons. ("user_btn", 0, Pins("E1"), IOStandard("LVCMOS33")), + # Leds. ("user_led", 0, Pins("A3"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("B3"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("B2"), IOStandard("LVCMOS33")), @@ -31,6 +36,7 @@ _io_r0_1 = [ ("user_led", 6, Pins("D1"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("D3"), IOStandard("LVCMOS33")), + # DDR3 SDRAM. ("ddram", 0, Subsignal("a", Pins( "F18 L17 D19 E18 H16 T20 U17 T17", @@ -46,40 +52,33 @@ _io_r0_1 = [ "R17 L19 R16 L16 M18 M19 N18 N17", "J19 C20 F19 E20 J18 K19 E19 G20"), IOStandard("SSTL135_I"), - Misc("TERMINATION=75")), # Misc("TERMINATION=75") Disabled to reduce heat + Misc("TERMINATION=75")), # Disable to reduce heat. Subsignal("dqs_p", Pins("N16 G19"), IOStandard("SSTL135D_I"), Misc("TERMINATION=OFF DIFFRESISTOR=100")), - Subsignal("clk_p", Pins("L20"), IOStandard("SSTL135D_I")), - Subsignal("cke", Pins("N19"), IOStandard("SSTL135_I")), - Subsignal("odt", Pins("T19"), IOStandard("SSTL135_I")), + Subsignal("clk_p", Pins("L20"), IOStandard("SSTL135D_I")), + Subsignal("cke", Pins("N19"), IOStandard("SSTL135_I")), + Subsignal("odt", Pins("T19"), IOStandard("SSTL135_I")), Subsignal("reset_n", Pins("T18"), IOStandard("SSTL135_I")), - #Subsignal("vccio", Pins("H15 J15 H14 L15 M15 L14"), IOStandard("SSTL135_II")), - #Subsignal("gnd", Pins("G15 K15"), IOStandard("SSTL135_II")), Misc("SLEWRATE=FAST") ), + # USB. ("usb", 0, - Subsignal("d_p", Pins("F4")), - Subsignal("d_n", Pins("E3")), + Subsignal("d_p", Pins("F4")), + Subsignal("d_n", Pins("E3")), Subsignal("pullup", Pins("F5")), IOStandard("LVCMOS33") ), - ("uart", 0, - Subsignal("rx", Pins("N4"), Misc("PULLMODE=UP"), IOStandard("LVCMOS33")), - Subsignal("tx", Pins("N3"), Misc("PULLMODE=NONE"), IOStandard("LVCMOS33")), - Subsignal("tx_enable", Pins("T1"), Misc("PULLMODE=UP")), - IOStandard("LVCMOS33") - ), - # Serial + # Serial. ("serial", 0, - Subsignal("rx", Pins("N4"), Misc("PULLMODE=UP"), IOStandard("LVCMOS33")), - Subsignal("tx", Pins("N3"), Misc("PULLMODE=NONE"), IOStandard("LVCMOS33")), + Subsignal("rx", Pins("N4"), Misc("PULLMODE=UP"), IOStandard("LVCMOS33")), + Subsignal("tx", Pins("N3"), Misc("PULLMODE=NONE"), IOStandard("LVCMOS33")), Subsignal("tx_enable", Pins("T1"), Misc("PULLMODE=UP")), IOStandard("LVCMOS33") ), - # SPIFlash + # SPIFlash. ("spiflash", 0, Subsignal("cs_n", Pins("R2")), Subsignal("miso", Pins("V2")), @@ -94,6 +93,7 @@ _io_r0_1 = [ IOStandard("LVCMOS33") ), + # SDCard. ("sdcard", 0, Subsignal("clk", Pins("G1")), Subsignal("cmd", Pins("P1"), Misc("PULLMODE=UP")), @@ -155,10 +155,9 @@ feather_spi = [ ) ] - # Platform ----------------------------------------------------------------------------------------- -class Platform(LatticePlatform): +class Platform(LatticeECP5Platform): default_clk_name = "clk25" default_clk_period = 1e9/25e6 @@ -167,11 +166,11 @@ class Platform(LatticePlatform): self.revision = revision io = {"0.1": _io_r0_1}[revision] connectors = {"0.1": _connectors_r0_1}[revision] - LatticePlatform.__init__(self, f"LFE5UM5G-85F-8BG381C", io, connectors, **kwargs) + LatticeECP5Platform.__init__(self, f"LFE5UM5G-{device}-8BG381C", io, connectors, **kwargs) # def create_programmer(self): # return DFUProg(vid="1209", pid="5af0") def do_finalize(self, fragment): - LatticePlatform.do_finalize(self, fragment) + LatticeECP5Platform.do_finalize(self, fragment) self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6) diff --git a/litex_boards/targets/radiona_ulx4m_ld_v2.py b/litex_boards/targets/radiona_ulx4m_ld_v2.py old mode 100644 new mode 100755 index 498ba9c..72ddc74 --- a/litex_boards/targets/radiona_ulx4m_ld_v2.py +++ b/litex_boards/targets/radiona_ulx4m_ld_v2.py @@ -3,13 +3,12 @@ # # This file is part of LiteX-Boards. # -# Copyright (c) 2021 Florent Kermarrec -# Copyright (c) 2021 Greg Davill # Copyright (c) 2022 Goran Mahovlic +# Copyright (c) 2021 Greg Davill # SPDX-License-Identifier: BSD-2-Clause # Build/Use: -# ./gsd_ulx4m_ld.py --uart-name=uart --uart-baudrate=115200 --sdram-device MT41K64M16 --csr-csv=csr.csv --build +# ./radiona_ulx4m_ld_v3.py --uart-name=uart --uart-baudrate=115200 --sdram-device MT41K64M16 --csr-csv=csr.csv --build import os import sys @@ -18,9 +17,8 @@ import argparse from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer -from litex_boards.platforms import ulx4m_ld_v2 - -from litex.build.lattice.trellis import trellis_args, trellis_argdict +from litex.gen import LiteXModule +from litex_boards.platforms import radiona_ulx4m_ld_v2 from litex.soc.cores.clock import * from litex.soc.integration.soc_core import * @@ -35,16 +33,16 @@ from litedram.phy import ECP5DDRPHY from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII -# CRG --------------------------------------------------------------------------------------------- +# CRG ---------------------------------------------------------------------------------------------- -class _CRG(Module): +class _CRG(LiteXModule): def __init__(self, platform, sys_clk_freq, with_video_pll=True): self.rst = Signal() - self.clock_domains.cd_init = ClockDomain() - self.clock_domains.cd_por = ClockDomain(reset_less=True) - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys2x = ClockDomain() - self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True) + self.cd_init = ClockDomain() + self.cd_por = ClockDomain(reset_less=True) + self.cd_sys = ClockDomain() + self.cd_sys2x = ClockDomain() + self.cd_sys2x_i = ClockDomain(reset_less=True) # # # @@ -62,28 +60,18 @@ class _CRG(Module): self.comb += por_done.eq(por_count == 0) self.sync.por += If(~por_done, por_count.eq(por_count - 1)) - # USB PLL -# if with_usb_pll: -# self.submodules.usb_pll = usb_pll = ECP5PLL() -# self.comb += usb_pll.reset.eq(rst | self.rst) -# usb_pll.register_clkin(clk25, 25e6) -# self.clock_domains.cd_usb_12 = ClockDomain() -# self.clock_domains.cd_usb_48 = ClockDomain() -# usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0) -# usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0) - # Video PLL if with_video_pll: - self.submodules.video_pll = video_pll = ECP5PLL() + self.video_pll = video_pll = ECP5PLL() self.comb += video_pll.reset.eq(rst_n | self.rst) video_pll.register_clkin(clk25, 25e6) - self.clock_domains.cd_hdmi = ClockDomain() - self.clock_domains.cd_hdmi5x = ClockDomain() + self.cd_hdmi = ClockDomain() + self.cd_hdmi5x = ClockDomain() video_pll.create_clkout(self.cd_hdmi, 25e6, margin=0) video_pll.create_clkout(self.cd_hdmi5x, 125e6, margin=0) # PLL - self.submodules.pll = pll = ECP5PLL() + self.pll = pll = ECP5PLL() self.comb += pll.reset.eq(~por_done | rst_n | self.rst) pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq) @@ -105,33 +93,30 @@ class _CRG(Module): # BaseSoC ------------------------------------------------------------------------------------------ -# revision = kwargs.get("revision", "0.1") -# device = kwargs.get("device", "UM-45F") - class BaseSoC(SoCCore): - def __init__(self, revision="0.1", device="UM5G-85F", sdram_device="MT41K512M16", sys_clk_freq=int(100e6), - toolchain="trellis", with_ethernet=False, with_etherbone=False, - with_video_terminal=True, - with_video_framebuffer=False, - eth_ip="192.168.1.50", - eth_dynamic_ip = False, - with_spi_flash = False, - with_led_chaser = True, - with_syzygy_gpio = False, + def __init__(self, revision="0.1", device="85F", toolchain="trellis", sys_clk_freq=int(100e6), + sdram_device = "MT41K512M16", + with_ethernet = False, + with_etherbone = False, + with_video_terminal = True, + with_video_framebuffer = False, + eth_ip = "192.168.1.50", + eth_dynamic_ip = False, + with_spi_flash = False, + with_led_chaser = True, + with_syzygy_gpio = False, **kwargs) : - platform = ulx4m_ld_v2.Platform(revision="0.1", device="UM5G-85F" ,toolchain="trellis") - - # SoCCore ---------------------------------------------------------------------------------- - if kwargs["uart_name"] in ["serial", "usb_acm"]: - kwargs["uart_name"] = "serial" - SoCCore.__init__(self, platform, sys_clk_freq, - ident = "LiteX SoC on ULX4M-LD-V2", - **kwargs) + platform = radiona_ulx4m_ld_v2.Platform(revision="0.1", device=device ,toolchain=toolchain) # CRG -------------------------------------------------------------------------------------- with_video_pll = with_video_terminal or with_video_framebuffer self.submodules.crg = _CRG(platform, sys_clk_freq, with_video_pll) + # SoCCore ---------------------------------------------------------------------------------- + if kwargs["uart_name"] in ["serial", "usb_acm"]: + kwargs["uart_name"] = "serial" + SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on ULX4M-LD-V2", **kwargs) + # DDR3 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: available_sdram_modules = { @@ -192,14 +177,12 @@ class BaseSoC(SoCCore): # Build -------------------------------------------------------------------------------------------- def main(): - parser = LiteXArgumentParser(platform=radiona_ulx4m_ld_v2.Platform, description="LiteX SoC on ULX4M-LD-V2") - 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 toolchain (trellis or diamond).") - parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.") + from litex.build.parser import LiteXArgumentParser + parser = LiteXArgumentParser(platform=radiona_ulx4m_ld_v2.Platform, description="LiteX SoC on ULX4M-LD-V2") + parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.") parser.add_argument("--revision", default="1.0", help="Board Revision (1.0).") - parser.add_argument("--device", default="UM5G-85F", help="ECP5 device (25F, 45F, 85F).") - parser.add_argument("--sdram-device", default="MT41K32M16", help="SDRAM device (MT41K64M16, MT41K128M16, MT41K256M16 or MT41K512M16).") + parser.add_argument("--device", default="85F", help="ECP5 device (25F, 45F, 85F).") + parser.add_argument("--sdram-device", default="MT41K512M16", help="SDRAM device (MT41K64M16, MT41K128M16, MT41K256M16 or MT41K512M16).") ethopts = parser.add_mutually_exclusive_group() ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet.") ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone.") @@ -213,35 +196,32 @@ def main(): viopts = parser.add_mutually_exclusive_group() viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI).") viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI).") - builder_args(parser) - soc_core_args(parser) - trellis_args(parser) args = parser.parse_args() assert not (args.with_etherbone and args.eth_dynamic_ip) soc = BaseSoC( - toolchain = args.toolchain, - revision = args.revision, - device = args.device, - sdram_device = args.sdram_device, - sys_clk_freq = int(float(args.sys_clk_freq)), - with_ethernet = args.with_ethernet, - with_etherbone = args.with_etherbone, - eth_ip = args.eth_ip, - eth_dynamic_ip = args.eth_dynamic_ip, - with_spi_flash = args.with_spi_flash, + toolchain = args.toolchain, + revision = args.revision, + device = args.device, + sdram_device = args.sdram_device, + sys_clk_freq = int(float(args.sys_clk_freq)), + with_ethernet = args.with_ethernet, + with_etherbone = args.with_etherbone, + eth_ip = args.eth_ip, + eth_dynamic_ip = args.eth_dynamic_ip, + with_spi_flash = args.with_spi_flash, with_video_terminal = args.with_video_terminal, with_video_framebuffer = args.with_video_framebuffer, - with_syzygy_gpio = args.with_syzygy_gpio, - **soc_core_argdict(args)) + with_syzygy_gpio = args.with_syzygy_gpio, + **parser.soc_argdict) if args.with_spi_sdcard: soc.add_spi_sdcard() if args.with_sdcard: soc.add_sdcard() - builder = Builder(soc, **builder_argdict(args)) - builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {} - builder.build(**builder_kargs, run=args.build) + builder = Builder(soc, **parser.builder_argdict) + if args.build: + builder.build(**parser.toolchain_argdict) if args.load: prog = soc.platform.create_programmer()