radiona_ulx4m_ld_v2: Do a first review/cleanup path.

This commit is contained in:
Florent Kermarrec 2023-02-13 16:11:32 +01:00
parent 386cc1284d
commit fdffeb8474
2 changed files with 74 additions and 95 deletions

View File

@ -1,27 +1,32 @@
# #
# This file is part of LiteX-Boards. # This file is part of LiteX-Boards.
# #
# Copyright (c) 2022 Goran Mahovlic <goran.mahovlic@gmail.com>
# Copyright (c) 2020 Greg Davill <greg.davill@gmail.com> # Copyright (c) 2020 Greg Davill <greg.davill@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import * from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform from litex.build.lattice import LatticeECP5Platform
#from litex.build.dfu import DFUProg #from litex.build.dfu import DFUProg
# IOs ---------------------------------------------------------------------------------------------- # IOs ----------------------------------------------------------------------------------------------
_io_r0_1 = [ _io_r0_1 = [
# Clk/Rst.
("clk25", 0, Pins("G2"), IOStandard("LVCMOS33")), ("clk25", 0, Pins("G2"), IOStandard("LVCMOS33")),
("rst_n", 0, Pins("F1"), IOStandard("LVCMOS33")), ("rst_n", 0, Pins("F1"), IOStandard("LVCMOS33")),
# RGB Led.
("rgb_led", 0, ("rgb_led", 0,
Subsignal("r", Pins("A3"), IOStandard("LVCMOS33")), Subsignal("r", Pins("A3"), IOStandard("LVCMOS33")),
Subsignal("g", Pins("B3"), IOStandard("LVCMOS33")), Subsignal("g", Pins("B3"), IOStandard("LVCMOS33")),
Subsignal("b", Pins("B2"), IOStandard("LVCMOS33")), Subsignal("b", Pins("B2"), IOStandard("LVCMOS33")),
), ),
# Buttons.
("user_btn", 0, Pins("E1"), IOStandard("LVCMOS33")), ("user_btn", 0, Pins("E1"), IOStandard("LVCMOS33")),
# Leds.
("user_led", 0, Pins("A3"), IOStandard("LVCMOS33")), ("user_led", 0, Pins("A3"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("B3"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("B3"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("B2"), 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", 6, Pins("D1"), IOStandard("LVCMOS33")),
("user_led", 7, Pins("D3"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("D3"), IOStandard("LVCMOS33")),
# DDR3 SDRAM.
("ddram", 0, ("ddram", 0,
Subsignal("a", Pins( Subsignal("a", Pins(
"F18 L17 D19 E18 H16 T20 U17 T17", "F18 L17 D19 E18 H16 T20 U17 T17",
@ -46,40 +52,33 @@ _io_r0_1 = [
"R17 L19 R16 L16 M18 M19 N18 N17", "R17 L19 R16 L16 M18 M19 N18 N17",
"J19 C20 F19 E20 J18 K19 E19 G20"), "J19 C20 F19 E20 J18 K19 E19 G20"),
IOStandard("SSTL135_I"), 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"), Subsignal("dqs_p", Pins("N16 G19"), IOStandard("SSTL135D_I"),
Misc("TERMINATION=OFF DIFFRESISTOR=100")), Misc("TERMINATION=OFF DIFFRESISTOR=100")),
Subsignal("clk_p", Pins("L20"), IOStandard("SSTL135D_I")), Subsignal("clk_p", Pins("L20"), IOStandard("SSTL135D_I")),
Subsignal("cke", Pins("N19"), IOStandard("SSTL135_I")), Subsignal("cke", Pins("N19"), IOStandard("SSTL135_I")),
Subsignal("odt", Pins("T19"), IOStandard("SSTL135_I")), Subsignal("odt", Pins("T19"), IOStandard("SSTL135_I")),
Subsignal("reset_n", Pins("T18"), 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") Misc("SLEWRATE=FAST")
), ),
# USB.
("usb", 0, ("usb", 0,
Subsignal("d_p", Pins("F4")), Subsignal("d_p", Pins("F4")),
Subsignal("d_n", Pins("E3")), Subsignal("d_n", Pins("E3")),
Subsignal("pullup", Pins("F5")), Subsignal("pullup", Pins("F5")),
IOStandard("LVCMOS33") 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, ("serial", 0,
Subsignal("rx", Pins("N4"), Misc("PULLMODE=UP"), IOStandard("LVCMOS33")), Subsignal("rx", Pins("N4"), Misc("PULLMODE=UP"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("N3"), Misc("PULLMODE=NONE"), IOStandard("LVCMOS33")), Subsignal("tx", Pins("N3"), Misc("PULLMODE=NONE"), IOStandard("LVCMOS33")),
Subsignal("tx_enable", Pins("T1"), Misc("PULLMODE=UP")), Subsignal("tx_enable", Pins("T1"), Misc("PULLMODE=UP")),
IOStandard("LVCMOS33") IOStandard("LVCMOS33")
), ),
# SPIFlash # SPIFlash.
("spiflash", 0, ("spiflash", 0,
Subsignal("cs_n", Pins("R2")), Subsignal("cs_n", Pins("R2")),
Subsignal("miso", Pins("V2")), Subsignal("miso", Pins("V2")),
@ -94,6 +93,7 @@ _io_r0_1 = [
IOStandard("LVCMOS33") IOStandard("LVCMOS33")
), ),
# SDCard.
("sdcard", 0, ("sdcard", 0,
Subsignal("clk", Pins("G1")), Subsignal("clk", Pins("G1")),
Subsignal("cmd", Pins("P1"), Misc("PULLMODE=UP")), Subsignal("cmd", Pins("P1"), Misc("PULLMODE=UP")),
@ -155,10 +155,9 @@ feather_spi = [
) )
] ]
# Platform ----------------------------------------------------------------------------------------- # Platform -----------------------------------------------------------------------------------------
class Platform(LatticePlatform): class Platform(LatticeECP5Platform):
default_clk_name = "clk25" default_clk_name = "clk25"
default_clk_period = 1e9/25e6 default_clk_period = 1e9/25e6
@ -167,11 +166,11 @@ class Platform(LatticePlatform):
self.revision = revision self.revision = revision
io = {"0.1": _io_r0_1}[revision] io = {"0.1": _io_r0_1}[revision]
connectors = {"0.1": _connectors_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): # def create_programmer(self):
# return DFUProg(vid="1209", pid="5af0") # return DFUProg(vid="1209", pid="5af0")
def do_finalize(self, fragment): 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) self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6)

124
litex_boards/targets/radiona_ulx4m_ld_v2.py Normal file → Executable file
View File

@ -3,13 +3,12 @@
# #
# This file is part of LiteX-Boards. # This file is part of LiteX-Boards.
# #
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2021 Greg Davill <greg.davill@gmail.com>
# Copyright (c) 2022 Goran Mahovlic <goran.mahovlic@gmail.com> # Copyright (c) 2022 Goran Mahovlic <goran.mahovlic@gmail.com>
# Copyright (c) 2021 Greg Davill <greg.davill@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
# Build/Use: # 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 os
import sys import sys
@ -18,9 +17,8 @@ import argparse
from migen import * from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from litex_boards.platforms import ulx4m_ld_v2 from litex.gen import LiteXModule
from litex_boards.platforms import radiona_ulx4m_ld_v2
from litex.build.lattice.trellis import trellis_args, trellis_argdict
from litex.soc.cores.clock import * from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import * from litex.soc.integration.soc_core import *
@ -35,16 +33,16 @@ from litedram.phy import ECP5DDRPHY
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII 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): def __init__(self, platform, sys_clk_freq, with_video_pll=True):
self.rst = Signal() self.rst = Signal()
self.clock_domains.cd_init = ClockDomain() self.cd_init = ClockDomain()
self.clock_domains.cd_por = ClockDomain(reset_less=True) self.cd_por = ClockDomain(reset_less=True)
self.clock_domains.cd_sys = ClockDomain() self.cd_sys = ClockDomain()
self.clock_domains.cd_sys2x = ClockDomain() self.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True) self.cd_sys2x_i = ClockDomain(reset_less=True)
# # # # # #
@ -62,28 +60,18 @@ class _CRG(Module):
self.comb += por_done.eq(por_count == 0) self.comb += por_done.eq(por_count == 0)
self.sync.por += If(~por_done, por_count.eq(por_count - 1)) 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 # Video PLL
if with_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) self.comb += video_pll.reset.eq(rst_n | self.rst)
video_pll.register_clkin(clk25, 25e6) video_pll.register_clkin(clk25, 25e6)
self.clock_domains.cd_hdmi = ClockDomain() self.cd_hdmi = ClockDomain()
self.clock_domains.cd_hdmi5x = ClockDomain() self.cd_hdmi5x = ClockDomain()
video_pll.create_clkout(self.cd_hdmi, 25e6, margin=0) video_pll.create_clkout(self.cd_hdmi, 25e6, margin=0)
video_pll.create_clkout(self.cd_hdmi5x, 125e6, margin=0) video_pll.create_clkout(self.cd_hdmi5x, 125e6, margin=0)
# PLL # PLL
self.submodules.pll = pll = ECP5PLL() self.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~por_done | rst_n | self.rst) self.comb += pll.reset.eq(~por_done | rst_n | self.rst)
pll.register_clkin(clk25, 25e6) pll.register_clkin(clk25, 25e6)
pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq) pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
@ -105,33 +93,30 @@ class _CRG(Module):
# BaseSoC ------------------------------------------------------------------------------------------ # BaseSoC ------------------------------------------------------------------------------------------
# revision = kwargs.get("revision", "0.1")
# device = kwargs.get("device", "UM-45F")
class BaseSoC(SoCCore): class BaseSoC(SoCCore):
def __init__(self, revision="0.1", device="UM5G-85F", sdram_device="MT41K512M16", sys_clk_freq=int(100e6), def __init__(self, revision="0.1", device="85F", toolchain="trellis", sys_clk_freq=int(100e6),
toolchain="trellis", with_ethernet=False, with_etherbone=False, sdram_device = "MT41K512M16",
with_video_terminal=True, with_ethernet = False,
with_video_framebuffer=False, with_etherbone = False,
eth_ip="192.168.1.50", with_video_terminal = True,
eth_dynamic_ip = False, with_video_framebuffer = False,
with_spi_flash = False, eth_ip = "192.168.1.50",
with_led_chaser = True, eth_dynamic_ip = False,
with_syzygy_gpio = False, with_spi_flash = False,
with_led_chaser = True,
with_syzygy_gpio = False,
**kwargs) : **kwargs) :
platform = ulx4m_ld_v2.Platform(revision="0.1", device="UM5G-85F" ,toolchain="trellis") platform = radiona_ulx4m_ld_v2.Platform(revision="0.1", device=device ,toolchain=toolchain)
# 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)
# CRG -------------------------------------------------------------------------------------- # CRG --------------------------------------------------------------------------------------
with_video_pll = with_video_terminal or with_video_framebuffer with_video_pll = with_video_terminal or with_video_framebuffer
self.submodules.crg = _CRG(platform, sys_clk_freq, with_video_pll) 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 ------------------------------------------------------------------------------- # DDR3 SDRAM -------------------------------------------------------------------------------
if not self.integrated_main_ram_size: if not self.integrated_main_ram_size:
available_sdram_modules = { available_sdram_modules = {
@ -192,14 +177,12 @@ class BaseSoC(SoCCore):
# Build -------------------------------------------------------------------------------------------- # Build --------------------------------------------------------------------------------------------
def main(): def main():
parser = LiteXArgumentParser(platform=radiona_ulx4m_ld_v2.Platform, description="LiteX SoC on ULX4M-LD-V2") from litex.build.parser import LiteXArgumentParser
parser.add_argument("--build", action="store_true", help="Build bitstream.") parser = LiteXArgumentParser(platform=radiona_ulx4m_ld_v2.Platform, description="LiteX SoC on ULX4M-LD-V2")
parser.add_argument("--load", action="store_true", help="Load bitstream.") parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.")
parser.add_argument("--toolchain", default="trellis", help="FPGA toolchain (trellis or diamond).")
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("--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("--device", default="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("--sdram-device", default="MT41K512M16", help="SDRAM device (MT41K64M16, MT41K128M16, MT41K256M16 or MT41K512M16).")
ethopts = parser.add_mutually_exclusive_group() ethopts = parser.add_mutually_exclusive_group()
ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet.") ethopts.add_argument("--with-ethernet", action="store_true", help="Add Ethernet.")
ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone.") ethopts.add_argument("--with-etherbone", action="store_true", help="Add EtherBone.")
@ -213,35 +196,32 @@ def main():
viopts = parser.add_mutually_exclusive_group() 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-terminal", action="store_true", help="Enable Video Terminal (HDMI).")
viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (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() args = parser.parse_args()
assert not (args.with_etherbone and args.eth_dynamic_ip) assert not (args.with_etherbone and args.eth_dynamic_ip)
soc = BaseSoC( soc = BaseSoC(
toolchain = args.toolchain, toolchain = args.toolchain,
revision = args.revision, revision = args.revision,
device = args.device, device = args.device,
sdram_device = args.sdram_device, sdram_device = args.sdram_device,
sys_clk_freq = int(float(args.sys_clk_freq)), sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet, with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone, with_etherbone = args.with_etherbone,
eth_ip = args.eth_ip, eth_ip = args.eth_ip,
eth_dynamic_ip = args.eth_dynamic_ip, eth_dynamic_ip = args.eth_dynamic_ip,
with_spi_flash = args.with_spi_flash, with_spi_flash = args.with_spi_flash,
with_video_terminal = args.with_video_terminal, with_video_terminal = args.with_video_terminal,
with_video_framebuffer = args.with_video_framebuffer, with_video_framebuffer = args.with_video_framebuffer,
with_syzygy_gpio = args.with_syzygy_gpio, with_syzygy_gpio = args.with_syzygy_gpio,
**soc_core_argdict(args)) **parser.soc_argdict)
if args.with_spi_sdcard: if args.with_spi_sdcard:
soc.add_spi_sdcard() soc.add_spi_sdcard()
if args.with_sdcard: if args.with_sdcard:
soc.add_sdcard() soc.add_sdcard()
builder = Builder(soc, **builder_argdict(args)) builder = Builder(soc, **parser.builder_argdict)
builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {} if args.build:
builder.build(**builder_kargs, run=args.build) builder.build(**parser.toolchain_argdict)
if args.load: if args.load:
prog = soc.platform.create_programmer() prog = soc.platform.create_programmer()