Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Some of the suported boards, see yours? Give LiteX-Boards a try!
├── aliexpress_xc7k70t
├── alinx_ax7010
├── alinx_ax7020
├── alinx_ax7203
├── alinx_axu2cga
├── analog_pocket
├── antmicro_artix_dc_scm
Expand Down
136 changes: 136 additions & 0 deletions litex_boards/platforms/alinx_ax7203.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2025 Aaron Hagan <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause
#
# The AX7203 FPGA development board equipped with the AMD Artix 7 series device.
# https://en.alinx.com/Product/FPGA-Development-Boards/Artix-7/AX7203.html

import subprocess

from litex.build.generic_platform import *
from litex.build.xilinx import Xilinx7SeriesPlatform
from litex.build.openfpgaloader import OpenFPGALoader

# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk200", 0,
Subsignal("p", Pins("R4"), IOStandard("DIFF_SSTL15")),
Subsignal("n", Pins("T4"), IOStandard("DIFF_SSTL15")),
),
("cpu_reset_n", 0, Pins("T6"), IOStandard("LVCMOS15")),

("clk148p5", 0,
Subsignal("p", Pins("F6"), IOStandard("LVCMOS33")),
Subsignal("n", Pins("E6"), IOStandard("LVCMOS33"))
),

# Serial
("serial", 0,
Subsignal("tx", Pins("N15"), IOStandard("LVCMOS33")),
Subsignal("rx", Pins("P20"), IOStandard("LVCMOS33")),
),

# PCIe x4
("pcie_x4", 0,
Subsignal("rst_n", Pins("J20"), IOStandard("LVCMOS33")),
Subsignal("clk_p", Pins("F10")),
Subsignal("clk_n", Pins("E10")),
Subsignal("rx_p", Pins("D11 B8 B10 D9")),
Subsignal("rx_n", Pins("C11 A8 A10 C9")),
Subsignal("tx_p", Pins("D5 B4 B6 D7")),
Subsignal("tx_n", Pins("C5 A4 A6 C7"))
),

# Leds
("user_led", 0, Pins("B13"), IOStandard("LVCMOS18")),
("user_led", 1, Pins("C13"), IOStandard("LVCMOS18")),
("user_led", 2, Pins("D14"), IOStandard("LVCMOS18")),
("user_led", 3, Pins("D15"), IOStandard("LVCMOS18")),

# DDR3 SDRAM
("ddram", 0,
Subsignal("a", Pins("AA4 AB2 AA5 AB5 AB1 U3 W1 T1 V2 U2 Y1 W2 Y2 U1 V3"), IOStandard("SSTL15")),
Subsignal("ba", Pins("AA3 Y3 Y4"), IOStandard("SSTL15")),
Subsignal("ras_n", Pins("V4"), IOStandard("SSTL15")),
Subsignal("cas_n", Pins("W4"), IOStandard("SSTL15")),
Subsignal("we_n", Pins("AA1"), IOStandard("SSTL15")),
Subsignal("dm", Pins("D2 G2 M2 M5"), IOStandard("SSTL15")),
Subsignal("dq", Pins("C2 G1 A1 F3 B2 F1 B1 E2",
"H3 G3 H2 H5 J1 J5 K1 H4",
"L4 M3 L3 J6 K3 K6 J4 L5",
"P1 N4 R1 N2 M6 N5 P6 P2"),
IOStandard("SSTL15"),
Misc("IN_TERM=UNTUNED_SPLIT_50")),
Subsignal("dqs_p", Pins("E1 K2 M1 P5"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_50")),
Subsignal("dqs_n", Pins("D1 J2 L1 P4"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_50")),
Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15")),
Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15")),
Subsignal("cke", Pins("T5"), IOStandard("SSTL15")),
Subsignal("odt", Pins("U5"), IOStandard("SSTL15")),
Subsignal("reset_n", Pins("W6"), IOStandard("LVCMOS15")),
Subsignal("cs_n", Pins("AB3"), IOStandard("SSTL15")), # Fix me
Misc("SLEW=FAST"),
),

# SPIFlash
("flash_cs_n", 0, Pins("T19"), IOStandard("LVCMOS33")),
("flash", 0,
Subsignal("mosi", Pins("P22")),
Subsignal("miso", Pins("R22")),
Subsignal("wp", Pins("P21")),
Subsignal("hold", Pins("R21")),
IOStandard("LVCMOS33"),
)
]

# Platform -----------------------------------------------------------------------------------------
class Platform(Xilinx7SeriesPlatform):
default_clk_name = "clk200"
default_clk_period = 1e9/200e6

def __init__(self):
Xilinx7SeriesPlatform.__init__(self, "xc7a200t-fbg484-2", _io, toolchain="vivado")
self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]")

self.toolchain.bitstream_commands = [
"set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]",
"set_property BITSTREAM.CONFIG.CONFIGRATE 16 [current_design]",
"set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]",
"set_property CFGBVS VCCO [current_design]",
"set_property CONFIG_VOLTAGE 3.3 [current_design]",
]

self.toolchain.additional_commands = [
# Non-Multiboot SPI-Flash bitstream generation.
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin",

# Multiboot SPI-Flash Operational bitstream generation.
"set_property BITSTREAM.CONFIG.TIMER_CFG 0x0001fbd0 [current_design]",
"set_property BITSTREAM.CONFIG.CONFIGFALLBACK Enable [current_design]",
"write_bitstream -force {build_name}_operational.bit ",
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_operational.bit\" -file {build_name}_operational.bin",

# Multiboot SPI-Flash Fallback bitstream generation.
"set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x00400000 [current_design]",
"write_bitstream -force {build_name}_fallback.bit ",
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_fallback.bit\" -file {build_name}_fallback.bin"
]

def detect_ftdi_chip(self):
lsusb_log = subprocess.run(['lsusb'], capture_output=True, text=True)
for ftdi_chip in ["ft232", "ft2232", "ft4232"]:
if f"Future Technology Devices International, Ltd {ftdi_chip.upper()}" in lsusb_log.stdout:
return ftdi_chip
return None

def create_programmer(self, name="openfpgaloader"):
ftdi_chip = self.detect_ftdi_chip()
return OpenFPGALoader(cable=ftdi_chip, fpga_part=f"xc7a200tfbg484", freq=10e6)

def do_finalize(self, fragment):
Xilinx7SeriesPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
140 changes: 140 additions & 0 deletions litex_boards/targets/alinx_ax7203.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/usr/bin/env python3

#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2025 Aaron Hagan <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

from migen import *

from litex.gen import *

from litex_boards.platforms import alinx_ax7203

from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser

from litepcie.phy.s7pciephy import S7PCIEPHY
from litepcie.software import generate_litepcie_software

from litedram.modules import MT41J256M16
from litedram.phy import s7ddrphy

# CRG ----------------------------------------------------------------------------------------------
class _CRG(LiteXModule):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.cd_sys = ClockDomain()
self.cd_sys4x = ClockDomain()
self.cd_sys4x_dqs = ClockDomain()
self.cd_idelay = ClockDomain()

# Clk.
clk200 = platform.request("clk200")

# Main PLL.
self.pll = pll = S7PLL(speedgrade=-2)
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(clk200, 200e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
pll.create_clkout(self.cd_idelay, 200e6)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)

# IDELAY Ctrl.
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)

# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self,
sys_clk_freq = int(200e6),
with_led_chaser = True,
with_pcie = False,
**kwargs):

platform = alinx_ax7203.Platform()

# CRG --------------------------------------------------------------------------------------
self.crg = _CRG(platform, sys_clk_freq)

# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on ALINX AX7203", **kwargs)

# DDR3 SDRAM -------------------------------------------------------------------------------
self.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
memtype = "DDR3",
nphases = 4,
sys_clk_freq = sys_clk_freq,
iodelay_clk_freq = 200e6)

self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41J256M16(sys_clk_freq, "1:4"),
l2_cache_size = kwargs.get("l2_size", 8192)
)

# PCIe -------------------------------------------------------------------------------------
if with_pcie:
self.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x4"),
data_width = 128,
bar0_size = 0x20000)
self.add_pcie(phy=self.pcie_phy, ndmas=1, address_width=64)
platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq)

# ICAP (For FPGA reload over PCIe).
from litex.soc.cores.icap import ICAP
self.icap = ICAP()
self.icap.add_reload()
self.icap.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)

# Flash (For SPIFlash update over PCIe).
from litex.soc.cores.gpio import GPIOOut
from litex.soc.cores.spi_flash import S7SPIFlash
self.flash_cs_n = GPIOOut(platform.request("flash_cs_n"))
self.flash = S7SPIFlash(platform.request("flash"), sys_clk_freq, 25e6)

# 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=alinx_ax7203.Platform, description="LiteX SoC on ALINX AX7203.")
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream.")
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
parser.add_target_argument("--with-pcie", action="store_true", help="Enable PCIe support.")
parser.add_target_argument("--driver", action="store_true", help="Generate drivers.")

args = parser.parse_args()

soc = BaseSoC(
sys_clk_freq = args.sys_clk_freq,
with_led_chaser = True,
with_pcie = args.with_pcie,
**parser.soc_argdict
)

builder = Builder(soc, **parser.builder_argdict)
if args.build:
builder.build(**parser.toolchain_argdict)

if args.driver:
generate_litepcie_software(soc, os.path.join(builder.output_dir, "driver"))

if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))

if args.flash:
prog = soc.platform.create_programmer()
prog.flash(0, builder.get_bitstream_filename(mode="flash"))

if __name__ == "__main__":
main()