Merge pull request #595 from trabucayre/lattice_certusnxpro

Lattice certusnxpro
This commit is contained in:
enjoy-digital 2024-06-28 13:26:47 +02:00 committed by GitHub
commit 40204ac815
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 469 additions and 0 deletions

View File

@ -162,6 +162,8 @@ 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_certuspro_nx_vvml
├── 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,116 @@
#
# 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 = [
# Figure A.6
("clk24", 0, Pins("M20"), IOStandard("LVCMOS18")),
("clk27", 0, Pins("M22"), IOStandard("LVCMOS18")),
# 8.1. General Purpose Push Buttons - all logic zero when pressed
("gsrn", 0, Pins("R5"), IOStandard("LVCMOS33")), # SW4
("programn", 0, Pins("C20"), IOStandard("LVCMOS33")), # SW5
("user_btn", 0, Pins("N1"), IOStandard("LVCMOS33")), # SW2
("user_btn", 1, Pins("N2"), IOStandard("LVCMOS33")), # SW3
# 8.1. DIP Switch
("user_dip_btn", 0, Pins("AA15"), IOStandard("LVCMOS33")),
("user_dip_btn", 1, Pins("AB16"), IOStandard("LVCMOS33")),
("user_dip_btn", 1, Pins("W16"), IOStandard("LVCMOS33")),
# Figure 8.1 UART Topology
("serial", 0,
Subsignal("rx", Pins("E22"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("D22"), IOStandard("LVCMOS33")),
),
# 7.1. General Purpose LEDs (Inverted)
("user_led", 0, Pins("M6"), IOStandard("LVCMOS33")), # Bank 6 Green
("user_led", 1, Pins("M7"), IOStandard("LVCMOS33")), # Bank 6 Green
("user_led", 2, Pins("N6"), IOStandard("LVCMOS33")), # Bank 6 Green
("user_led", 3, Pins("N5"), IOStandard("LVCMOS33")), # Bank 6 Green
("rgb_led", 0,
Subsignal("r", Pins("P2")), # Bank 6 LED4 Red
Subsignal("g", Pins("P1")), # Bank 6 LED4 Green
Subsignal("b", Pins("P3")), # Bank 6 LED4 Blue
IOStandard("LVCMOS33")
),
("rgb_led", 1,
Subsignal("r", Pins("R3")), # Bank 6 LED5 Red
Subsignal("g", Pins("R4")), # Bank 6 LED5 Green
Subsignal("b", Pins("P4")), # Bank 6 LED5 Blue
IOStandard("LVCMOS33")
),
("spiflash", 0,
Subsignal("cs_n", Pins("F17")),
Subsignal("clk", Pins("F15")),
Subsignal("mosi", Pins("E18")),
Subsignal("miso", Pins("C21")),
Subsignal("wp", Pins("C22")),
Subsignal("hold", Pins("E16")),
IOStandard("LVCMOS33")
),
("spiflash4x", 0,
Subsignal("cs_n", Pins("F17")),
Subsignal("clk", Pins("F15")),
Subsignal("dq", Pins("E18 C21 C22 E16")),
IOStandard("LVCMOS33")
),
# 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", "L6 L8 L10 K10 J6 H6 H7 H8"),
("PMOD1", "L1 K2 K3 J1 L2 M1 M2 K1"),
("PMOD2", "L4 H1 G5 J9 L3 J2 H4 G7"),
("PMOD3", "J7 K6 H5 K4 K8 J8 L9 K9"),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticeNexusPlatform):
default_clk_name = "clk24"
default_clk_period = 1e9/24e6
def __init__(self, device="LFCPNX", toolchain="radiant", **kwargs):
assert device in ["LFCPNX"]
LatticeNexusPlatform.__init__(self, device + "-100-9BBG484I", _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()

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_vvml
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("gsrn")
# 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_vvml.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 VVML 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_vvml.Platform, description="LiteX SoC on CertusPro-NX VVML 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()