Skip to content

Commit 1f86f7f

Browse files
authored
Merge pull request #678 from amhagan/AX7203
alinx_ax7203: Add AX7203 FPGA development board
2 parents 5d50ed1 + 9dfce6f commit 1f86f7f

File tree

3 files changed

+277
-0
lines changed

3 files changed

+277
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ Some of the suported boards, see yours? Give LiteX-Boards a try!
100100
├── aliexpress_xc7k70t
101101
├── alinx_ax7010
102102
├── alinx_ax7020
103+
├── alinx_ax7203
103104
├── alinx_axu2cga
104105
├── analog_pocket
105106
├── antmicro_artix_dc_scm
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#
2+
# This file is part of LiteX-Boards.
3+
#
4+
# Copyright (c) 2025 Aaron Hagan <[email protected]>
5+
# SPDX-License-Identifier: BSD-2-Clause
6+
#
7+
# The AX7203 FPGA development board equipped with the AMD Artix 7 series device.
8+
# https://en.alinx.com/Product/FPGA-Development-Boards/Artix-7/AX7203.html
9+
10+
import subprocess
11+
12+
from litex.build.generic_platform import *
13+
from litex.build.xilinx import Xilinx7SeriesPlatform
14+
from litex.build.openfpgaloader import OpenFPGALoader
15+
16+
# IOs ----------------------------------------------------------------------------------------------
17+
_io = [
18+
# Clk / Rst
19+
("clk200", 0,
20+
Subsignal("p", Pins("R4"), IOStandard("DIFF_SSTL15")),
21+
Subsignal("n", Pins("T4"), IOStandard("DIFF_SSTL15")),
22+
),
23+
("cpu_reset_n", 0, Pins("T6"), IOStandard("LVCMOS15")),
24+
25+
("clk148p5", 0,
26+
Subsignal("p", Pins("F6"), IOStandard("LVCMOS33")),
27+
Subsignal("n", Pins("E6"), IOStandard("LVCMOS33"))
28+
),
29+
30+
# Serial
31+
("serial", 0,
32+
Subsignal("tx", Pins("N15"), IOStandard("LVCMOS33")),
33+
Subsignal("rx", Pins("P20"), IOStandard("LVCMOS33")),
34+
),
35+
36+
# PCIe x4
37+
("pcie_x4", 0,
38+
Subsignal("rst_n", Pins("J20"), IOStandard("LVCMOS33")),
39+
Subsignal("clk_p", Pins("F10")),
40+
Subsignal("clk_n", Pins("E10")),
41+
Subsignal("rx_p", Pins("D11 B8 B10 D9")),
42+
Subsignal("rx_n", Pins("C11 A8 A10 C9")),
43+
Subsignal("tx_p", Pins("D5 B4 B6 D7")),
44+
Subsignal("tx_n", Pins("C5 A4 A6 C7"))
45+
),
46+
47+
# Leds
48+
("user_led", 0, Pins("B13"), IOStandard("LVCMOS18")),
49+
("user_led", 1, Pins("C13"), IOStandard("LVCMOS18")),
50+
("user_led", 2, Pins("D14"), IOStandard("LVCMOS18")),
51+
("user_led", 3, Pins("D15"), IOStandard("LVCMOS18")),
52+
53+
# DDR3 SDRAM
54+
("ddram", 0,
55+
Subsignal("a", Pins("AA4 AB2 AA5 AB5 AB1 U3 W1 T1 V2 U2 Y1 W2 Y2 U1 V3"), IOStandard("SSTL15")),
56+
Subsignal("ba", Pins("AA3 Y3 Y4"), IOStandard("SSTL15")),
57+
Subsignal("ras_n", Pins("V4"), IOStandard("SSTL15")),
58+
Subsignal("cas_n", Pins("W4"), IOStandard("SSTL15")),
59+
Subsignal("we_n", Pins("AA1"), IOStandard("SSTL15")),
60+
Subsignal("dm", Pins("D2 G2 M2 M5"), IOStandard("SSTL15")),
61+
Subsignal("dq", Pins("C2 G1 A1 F3 B2 F1 B1 E2",
62+
"H3 G3 H2 H5 J1 J5 K1 H4",
63+
"L4 M3 L3 J6 K3 K6 J4 L5",
64+
"P1 N4 R1 N2 M6 N5 P6 P2"),
65+
IOStandard("SSTL15"),
66+
Misc("IN_TERM=UNTUNED_SPLIT_50")),
67+
Subsignal("dqs_p", Pins("E1 K2 M1 P5"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_50")),
68+
Subsignal("dqs_n", Pins("D1 J2 L1 P4"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_50")),
69+
Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15")),
70+
Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15")),
71+
Subsignal("cke", Pins("T5"), IOStandard("SSTL15")),
72+
Subsignal("odt", Pins("U5"), IOStandard("SSTL15")),
73+
Subsignal("reset_n", Pins("W6"), IOStandard("LVCMOS15")),
74+
Subsignal("cs_n", Pins("AB3"), IOStandard("SSTL15")), # Fix me
75+
Misc("SLEW=FAST"),
76+
),
77+
78+
# SPIFlash
79+
("flash_cs_n", 0, Pins("T19"), IOStandard("LVCMOS33")),
80+
("flash", 0,
81+
Subsignal("mosi", Pins("P22")),
82+
Subsignal("miso", Pins("R22")),
83+
Subsignal("wp", Pins("P21")),
84+
Subsignal("hold", Pins("R21")),
85+
IOStandard("LVCMOS33"),
86+
)
87+
]
88+
89+
# Platform -----------------------------------------------------------------------------------------
90+
class Platform(Xilinx7SeriesPlatform):
91+
default_clk_name = "clk200"
92+
default_clk_period = 1e9/200e6
93+
94+
def __init__(self):
95+
Xilinx7SeriesPlatform.__init__(self, "xc7a200t-fbg484-2", _io, toolchain="vivado")
96+
self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
97+
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]")
98+
99+
self.toolchain.bitstream_commands = [
100+
"set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]",
101+
"set_property BITSTREAM.CONFIG.CONFIGRATE 16 [current_design]",
102+
"set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]",
103+
"set_property CFGBVS VCCO [current_design]",
104+
"set_property CONFIG_VOLTAGE 3.3 [current_design]",
105+
]
106+
107+
self.toolchain.additional_commands = [
108+
# Non-Multiboot SPI-Flash bitstream generation.
109+
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin",
110+
111+
# Multiboot SPI-Flash Operational bitstream generation.
112+
"set_property BITSTREAM.CONFIG.TIMER_CFG 0x0001fbd0 [current_design]",
113+
"set_property BITSTREAM.CONFIG.CONFIGFALLBACK Enable [current_design]",
114+
"write_bitstream -force {build_name}_operational.bit ",
115+
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_operational.bit\" -file {build_name}_operational.bin",
116+
117+
# Multiboot SPI-Flash Fallback bitstream generation.
118+
"set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x00400000 [current_design]",
119+
"write_bitstream -force {build_name}_fallback.bit ",
120+
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_fallback.bit\" -file {build_name}_fallback.bin"
121+
]
122+
123+
def detect_ftdi_chip(self):
124+
lsusb_log = subprocess.run(['lsusb'], capture_output=True, text=True)
125+
for ftdi_chip in ["ft232", "ft2232", "ft4232"]:
126+
if f"Future Technology Devices International, Ltd {ftdi_chip.upper()}" in lsusb_log.stdout:
127+
return ftdi_chip
128+
return None
129+
130+
def create_programmer(self, name="openfpgaloader"):
131+
ftdi_chip = self.detect_ftdi_chip()
132+
return OpenFPGALoader(cable=ftdi_chip, fpga_part=f"xc7a200tfbg484", freq=10e6)
133+
134+
def do_finalize(self, fragment):
135+
Xilinx7SeriesPlatform.do_finalize(self, fragment)
136+
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python3
2+
3+
#
4+
# This file is part of LiteX-Boards.
5+
#
6+
# Copyright (c) 2025 Aaron Hagan <[email protected]>
7+
# SPDX-License-Identifier: BSD-2-Clause
8+
9+
from migen import *
10+
11+
from litex.gen import *
12+
13+
from litex_boards.platforms import alinx_ax7203
14+
15+
from litex.soc.cores.clock import *
16+
from litex.soc.integration.soc_core import *
17+
from litex.soc.integration.builder import *
18+
from litex.soc.cores.led import LedChaser
19+
20+
from litepcie.phy.s7pciephy import S7PCIEPHY
21+
from litepcie.software import generate_litepcie_software
22+
23+
from litedram.modules import MT41J256M16
24+
from litedram.phy import s7ddrphy
25+
26+
# CRG ----------------------------------------------------------------------------------------------
27+
class _CRG(LiteXModule):
28+
def __init__(self, platform, sys_clk_freq):
29+
self.rst = Signal()
30+
self.cd_sys = ClockDomain()
31+
self.cd_sys4x = ClockDomain()
32+
self.cd_sys4x_dqs = ClockDomain()
33+
self.cd_idelay = ClockDomain()
34+
35+
# Clk.
36+
clk200 = platform.request("clk200")
37+
38+
# Main PLL.
39+
self.pll = pll = S7PLL(speedgrade=-2)
40+
self.comb += pll.reset.eq(self.rst)
41+
pll.register_clkin(clk200, 200e6)
42+
pll.create_clkout(self.cd_sys, sys_clk_freq)
43+
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
44+
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
45+
pll.create_clkout(self.cd_idelay, 200e6)
46+
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)
47+
48+
# IDELAY Ctrl.
49+
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
50+
51+
# BaseSoC ------------------------------------------------------------------------------------------
52+
class BaseSoC(SoCCore):
53+
def __init__(self,
54+
sys_clk_freq = int(200e6),
55+
with_led_chaser = True,
56+
with_pcie = False,
57+
**kwargs):
58+
59+
platform = alinx_ax7203.Platform()
60+
61+
# CRG --------------------------------------------------------------------------------------
62+
self.crg = _CRG(platform, sys_clk_freq)
63+
64+
# SoCCore ----------------------------------------------------------------------------------
65+
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on ALINX AX7203", **kwargs)
66+
67+
# DDR3 SDRAM -------------------------------------------------------------------------------
68+
self.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
69+
memtype = "DDR3",
70+
nphases = 4,
71+
sys_clk_freq = sys_clk_freq,
72+
iodelay_clk_freq = 200e6)
73+
74+
self.add_sdram("sdram",
75+
phy = self.ddrphy,
76+
module = MT41J256M16(sys_clk_freq, "1:4"),
77+
l2_cache_size = kwargs.get("l2_size", 8192)
78+
)
79+
80+
# PCIe -------------------------------------------------------------------------------------
81+
if with_pcie:
82+
self.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x4"),
83+
data_width = 128,
84+
bar0_size = 0x20000)
85+
self.add_pcie(phy=self.pcie_phy, ndmas=1, address_width=64)
86+
platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq)
87+
88+
# ICAP (For FPGA reload over PCIe).
89+
from litex.soc.cores.icap import ICAP
90+
self.icap = ICAP()
91+
self.icap.add_reload()
92+
self.icap.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
93+
94+
# Flash (For SPIFlash update over PCIe).
95+
from litex.soc.cores.gpio import GPIOOut
96+
from litex.soc.cores.spi_flash import S7SPIFlash
97+
self.flash_cs_n = GPIOOut(platform.request("flash_cs_n"))
98+
self.flash = S7SPIFlash(platform.request("flash"), sys_clk_freq, 25e6)
99+
100+
# Leds -------------------------------------------------------------------------------------
101+
if with_led_chaser:
102+
self.leds = LedChaser(
103+
pads = platform.request_all("user_led"),
104+
sys_clk_freq = sys_clk_freq)
105+
106+
# Build --------------------------------------------------------------------------------------------
107+
def main():
108+
from litex.build.parser import LiteXArgumentParser
109+
parser = LiteXArgumentParser(platform=alinx_ax7203.Platform, description="LiteX SoC on ALINX AX7203.")
110+
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream.")
111+
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
112+
parser.add_target_argument("--with-pcie", action="store_true", help="Enable PCIe support.")
113+
parser.add_target_argument("--driver", action="store_true", help="Generate drivers.")
114+
115+
args = parser.parse_args()
116+
117+
soc = BaseSoC(
118+
sys_clk_freq = args.sys_clk_freq,
119+
with_led_chaser = True,
120+
with_pcie = args.with_pcie,
121+
**parser.soc_argdict
122+
)
123+
124+
builder = Builder(soc, **parser.builder_argdict)
125+
if args.build:
126+
builder.build(**parser.toolchain_argdict)
127+
128+
if args.driver:
129+
generate_litepcie_software(soc, os.path.join(builder.output_dir, "driver"))
130+
131+
if args.load:
132+
prog = soc.platform.create_programmer()
133+
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
134+
135+
if args.flash:
136+
prog = soc.platform.create_programmer()
137+
prog.flash(0, builder.get_bitstream_filename(mode="flash"))
138+
139+
if __name__ == "__main__":
140+
main()

0 commit comments

Comments
 (0)