lattice_certuspro_nx_evn: new board support

This commit is contained in:
Gwenhael Goavec-Merou 2024-06-28 12:47:16 +02:00
parent bd58227c86
commit f27bbc9645
3 changed files with 248 additions and 0 deletions

View File

@ -162,6 +162,7 @@ Some of the suported boards, see yours? Give LiteX-Boards a try!
├── lambdaconcept_ecpix5
├── lambdaconcept_pcie_screamer_m2
├── lambdaconcept_pcie_screamer
├── lattice_certuspro_nx_evn
├── lattice_crosslink_nx_evn
├── lattice_crosslink_nx_vip
├── lattice_ecp5_evn

View File

@ -0,0 +1,143 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2024 Enjoy-Digital <enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.lattice import LatticeNexusPlatform
# IOs ----------------------------------------------------------------------------------------------
_io = [
# 5. CertusPro-NX Clock Sources
("clk125", 0, Pins("N25"), IOStandard("LVCMOS33")), # JP15: open
("clk12", 0, Pins("R4"), IOStandard("LVCMOS33")), # JP6: close
("clkresv", 0, Pins("R6"), IOStandard("LVCMOS33")), # DNI, JP18: open
# Disable Clk Signals
("resv_clk_dis", 0, Pins("R7"), IOStandard("LVCMOS33")),
("clk125_clk_dis", 0, Pins("J23"), IOStandard("LVCMOS33")),
# 7.2. General Purpose Push Buttons - all logic zero when pressed
("programn", 0, Pins("G4"), IOStandard("LVCMOS18")), # SW2
("user_btn", 0, Pins("J5"), IOStandard("LVCMOS18")), # SW1
("user_btn", 1, Pins("J2"), IOStandard("LVCMOS18")), # SW4
("user_btn", 2, Pins("J3"), IOStandard("LVCMOS18")), # SW5
# 7.1. DIP Switch
("user_dip_btn", 0, Pins("K8"), IOStandard("LVCMOS18")),
("user_dip_btn", 1, Pins("K7"), IOStandard("LVCMOS18")),
("user_dip_btn", 2, Pins("K6"), IOStandard("LVCMOS18")),
("user_dip_btn", 3, Pins("K4"), IOStandard("LVCMOS18")),
("user_dip_btn", 4, Pins("K3"), IOStandard("LVCMOS18")),
("user_dip_btn", 5, Pins("K2"), IOStandard("LVCMOS18")),
("user_dip_btn", 6, Pins("J7"), IOStandard("LVCMOS18")),
("user_dip_btn", 7, Pins("J6"), IOStandard("LVCMOS18")),
# 6.1 UART Topology (JP1/JP2: close, JP4/JP5: open)
("serial", 0,
Subsignal("rx", Pins("L2")),
Subsignal("tx", Pins("L1")),
IOStandard("LVCMOS33")
),
# 7.3. General Purpose LEDs (Inverted)
("user_led", 0, Pins("N5"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 1, Pins("N6"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 2, Pins("N7"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 3, Pins("N8"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 4, Pins("L6"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 5, Pins("N9"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 6, Pins("L8"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 7, Pins("M9"), IOStandard("LVCMOS33")), # Bank 1 Green
("user_led", 8, Pins("N1"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 9, Pins("N2"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 10, Pins("N3"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 11, Pins("M1"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 12, Pins("M2"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 13, Pins("M3"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 14, Pins("L3"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 15, Pins("N4"), IOStandard("LVCMOS33")), # Bank 1 Yellow
("user_led", 16, Pins("T4"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 17, Pins("T5"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 18, Pins("R6"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 19, Pins("T7"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 20, Pins("U8"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 21, Pins("T8"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 22, Pins("R9"), IOStandard("LVCMOS33")), # Bank 1 Red
("user_led", 23, Pins("P9"), IOStandard("LVCMOS33")), # Bank 1 Red
# 6.1 I2C Topology (connected to the FTDI with JP4/JP5
("i2c", 0,
Subsignal("scl", Pins("M7")),
Subsignal("sda", Pins("M6")),
IOStandard("LVCMOS33"),
),
# 6.3 SPI Topology
("spiflash", 0,
Subsignal("cs_n", Pins("H3")),
Subsignal("clk", Pins("G6")),
Subsignal("mosi", Pins("H7")),
Subsignal("miso", Pins("H6")),
Subsignal("wp", Pins("K5")),
Subsignal("hold", Pins("H4")),
IOStandard("LVCMOS18")
),
("spiflash4x", 0,
Subsignal("cs_n", Pins("H3")),
Subsignal("clk", Pins("G6")),
Subsignal("dq", Pins("H7 H6 K5 H4")),
IOStandard("LVCMOS18")
),
# HyperRAM
("hyperram", 0,
Subsignal("dq", Pins("V18 W19 AB19 AB20 AB21 AB18 AA17 W18"), IOStandard("LVCMOS18H")),
Subsignal("rwds", Pins("V19"), IOStandard("LVCMOS18H")),
Subsignal("cs_n", Pins("AA18"), IOStandard("LVCMOS18H")),
Subsignal("rst_n", Pins("AB17"), IOStandard("LVCMOS18H")),
Subsignal("clk", Pins("Y19"), IOStandard("LVDS")),
# Subsignal("clk_n", Pins("Y18"), IOStandard("LVDS")),
Misc("SLEWRATE=FAST")
),
("hyperram", 1,
Subsignal("dq", Pins("V22 AA20 V21 U21 U20 Y22 AA22 AA21"), IOStandard("LVCMOS18H")),
Subsignal("rwds", Pins("Y21"), IOStandard("LVCMOS18H")),
Subsignal("cs_n", Pins("AA19"), IOStandard("LVCMOS18H")),
Subsignal("rst_n", Pins("U18"), IOStandard("LVCMOS18H")),
Subsignal("clk", Pins("W22"), IOStandard("LVDS")),
# Subsignal("clk_n", Pins("W21"), IOStandard("LVDS")),
Misc("SLEWRATE=FAST")
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
# Table 6.2 PMOD Header
# PMOD signal number:
# 1 2 3 4 7 8 9 10
("PMOD0", "Y1 W2 V3 V1 Y2 W3 W1 V2"), # J5
("PMOD1", "V7 V6 V5 V4 V8 W7 W6 W5"), # J4
("PMOD2", "AA4 AB3 AA2 AA1 W4 Y4 AB2 AB1"), # J6
# FIXME SMA Header, FMC, TP and RPi Board header
]
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticeNexusPlatform):
default_clk_name = "clk125"
default_clk_period = 1e9/125e6
def __init__(self, device="LFCPNX", toolchain="radiant", **kwargs):
assert device in ["LFCPNX"]
LatticeNexusPlatform.__init__(self, device + "-100-9LFG672C", _io, _connectors, toolchain=toolchain, **kwargs)
# Evaluation mode (with free license)
self.toolchain.set_prj_strategy_opts({"bit_ip_eval": "true"})
def create_programmer(self):
return OpenFPGALoader()

View File

@ -0,0 +1,104 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2024 Enjoy-Digital <enjoy-digital.fr>
#
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.gen import *
from litex_boards.platforms import lattice_certuspro_nx_evn
from litex.build.io import CRG
from litex.build.generic_platform import *
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
# CRG ----------------------------------------------------------------------------------------------
class _CRG(LiteXModule):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.cd_sys = ClockDomain()
self.cd_por = ClockDomain()
# # #
# Clk / Rst
self.rst_n = platform.request("user_btn", 0)
# Clocking
self.sys_clk = sys_osc = NXOSCA()
sys_osc.create_hf_clk(self.cd_sys, sys_clk_freq)
platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq)
# Power on reset
por_count = Signal(16, reset=2**16-1)
por_done = Signal()
self.comb += por_done.eq(por_count == 0)
self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
self.specials += [
AsyncResetSynchronizer(self.cd_por, ~self.rst_n),
AsyncResetSynchronizer(self.cd_sys, ~por_done | self.rst)
]
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=75e6, toolchain="radiant",
with_led_chaser = True,
**kwargs):
platform = lattice_certuspro_nx_evn.Platform(toolchain=toolchain)
platform.add_platform_command("ldc_set_sysconfig {{MASTER_SPI_PORT=SERIAL}}")
# CRG --------------------------------------------------------------------------------------
self.crg = _CRG(platform, sys_clk_freq)
# SoCCore -----------------------------------------_----------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on CertusPro-NX Eval Board", **kwargs)
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
self.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
from litex.build.parser import LiteXArgumentParser
parser = LiteXArgumentParser(platform=lattice_certuspro_nx_evn.Platform, description="LiteX SoC on CertusPro-NX EVN Board.")
parser.add_target_argument("--sys-clk-freq", default=75e6, type=float, help="System clock frequency.")
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream to SPI Flash.")
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = args.sys_clk_freq,
**parser.soc_argdict
)
builder = Builder(soc, **parser.builder_argdict)
if args.build:
builder.build(**parser.toolchain_argdict)
if args.load:
prog = soc.platform.create_programmer(args.prog_target)
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
if args.flash:
prog = soc.platform.create_programmer(args.prog_target)
prog.load_bitstream(0, builder.get_bitstream_filename(mode="flash"))
if __name__ == "__main__":
main()