Skip to content

Commit

Permalink
Merge pull request #595 from trabucayre/lattice_certusnxpro
Browse files Browse the repository at this point in the history
Lattice certusnxpro
  • Loading branch information
enjoy-digital committed Jun 28, 2024
2 parents 5813df9 + 8579af5 commit 40204ac
Show file tree
Hide file tree
Showing 5 changed files with 469 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
143 changes: 143 additions & 0 deletions litex_boards/platforms/lattice_certuspro_nx_evn.py
Original file line number Diff line number Diff line change
@@ -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()
116 changes: 116 additions & 0 deletions litex_boards/platforms/lattice_certuspro_nx_vvml.py
Original file line number Diff line number Diff line change
@@ -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()
104 changes: 104 additions & 0 deletions litex_boards/targets/lattice_certuspro_nx_evn.py
Original file line number Diff line number Diff line change
@@ -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()
Loading

0 comments on commit 40204ac

Please sign in to comment.