Skip to content
Open
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
399 changes: 399 additions & 0 deletions amaranth_boards/alchitry_pt_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,399 @@
import os
import subprocess
import shutil

from amaranth.build import *
from amaranth.vendor import XilinxPlatform
from .resources import *


__all__ = ["AlchitryPtV2Platform"]


def find_loader():
loader_prgm = os.environ.get("ALCHITRY_LOADER", shutil.which("loader"))
if loader_prgm is None:
raise EnvironmentError(
"Could not find Alchrity Loader. Place "
"it directly in PATH or specify path explicitly via the "
"ALCHITRY_LOADER environment variable"
)
bridge_bin = os.environ.get(
"ALCHITRY_BRIDGE_BIN",
os.path.join(os.path.dirname(loader_prgm), "pt_v2_loader.bin"),
)
return (loader_prgm, bridge_bin)


# Based on pinouts published by Alchitry Labs, latest commit 7a6bd06d133ee2033c34f2e89a751889329da12b
# https://github.com/alchitry/Alchitry-Labs-V2/blob/master/src/main/kotlin/com/alchitry/labs2/hardware/pinout/PtV2TopPin.kt
# https://github.com/alchitry/Alchitry-Labs-V2/blob/master/src/main/kotlin/com/alchitry/labs2/hardware/pinout/PtV2AlphaTopPin.kt
# https://github.com/alchitry/Alchitry-Labs-V2/blob/master/src/main/kotlin/com/alchitry/labs2/hardware/pinout/PtV2BottomPin.kt


class AlchitryPtV2Platform(XilinxPlatform):
device = "xc7a100t"
package = "fgg484"
speed = "2"
default_clk = "clk100"

resources = [
Resource(
"clk100",
0,
Pins("W19", dir="i"),
Clock(100e6),
Attrs(IOSTANDARD="LVCMOS33"),
),
Resource("rst_n", 0, Pins("N15", dir="i"), Attrs(IOSTANDARD="LVCMOS33")),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use LEDResources.

Resource("led", 0, Pins("P19", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 1, Pins("P20", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 2, Pins("T21", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 3, Pins("R19", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 4, Pins("V22", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 5, Pins("U21", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 6, Pins("T20", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
Resource("led", 7, Pins("W20", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
# FTDI USB Interface
Resource(
"usb",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better name would be something like "ft232" (assuming it's that chip).

0,
Subsignal("rx", Pins("AA20", dir="i")),
Subsignal("tx", Pins("AA21", dir="o")),
# Note: The following D pins have different banks
Subsignal("d", Pins("W21 W22 Y21 Y22 F15 U7", dir="io")), # D2-D7
Subsignal("rxf_n", Pins("F21", dir="o")), # RXF#
Subsignal("txe_n", Pins("T3", dir="o")), # TXE#
Subsignal("rd_n", Pins("T16", dir="o")), # RD#
Subsignal("wr_n", Pins("U16", dir="o")), # WR#
Subsignal("siwua", Pins("Y17", dir="o")), # SIWUA
Attrs(IOSTANDARD="LVCMOS33"),
),
# QSPI Flash
Resource(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use SPIFlashResources.

"spi_flash",
0,
Subsignal("cs_n", Pins("T19", dir="o")),
# CLK is on a dedicated clock pin, but used as a standard IO for SPI
Subsignal("clk", Pins("L12", dir="o")),
Subsignal("dq", Pins("P22 R22 P21 R21", dir="io")), # D0, D1, D2, D3
Attrs(IOSTANDARD="LVCMOS33"),
),
# Analog differential pair (e.g., for XADC)
Resource("vp_vn", 0, DiffPairs("L10", "M9", dir="i")),
Copy link
Member

@whitequark whitequark Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be used as a Verilog input?

# DDR3 SDRAM
Resource(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use DDR3Resource.

"ddr3",
0,
Subsignal(
"a",
Pins(
"K14 M15 N18 K16 L14 K18 M13 L18 L13 M18 K13 L15 M16 L16", dir="o"
),
),
Subsignal("ba", Pins("K19 N20 M20", dir="o")),
Subsignal("cas_n", Pins("N22", dir="o")),
Subsignal("cke", Pins("M22", dir="o")),
Subsignal("clk", DiffPairs("K17", "J17", dir="o")),
Subsignal("cs_n", Pins("N19", dir="o")),
Subsignal("dm", Pins("H22 G13", dir="o")),
Subsignal(
"dq",
Pins(
"J22 M21 L21 J20 H20 G20 J21 H19 H13 G18 J15 H17 G15 G17 G16 H15",
dir="io",
),
),
Subsignal(
"dqs",
Subsignal("p", Pins("K21 J14", dir="io")),
Subsignal("n", Pins("K22 H14", dir="io")),
),
Subsignal("odt", Pins("M17", dir="o")),
Subsignal("ras_n", Pins("L20", dir="o")),
Subsignal("reset_n", Pins("J19", dir="o")),
Subsignal("we_n", Pins("L19", dir="o")),
Attrs(IOSTANDARD="SSTL135", SLEW="FAST"),
Attrs(IOSTANDARD="DIFF_SSTL135", SLEW="FAST", on="clk"),
Attrs(IOSTANDARD="DIFF_SSTL135", SLEW="FAST", on="dqs"),
),
]

connectors = [
Connector(
"top_a",
0,
{
"A3": "AB22",
"A4": "AB18",
"A5": "AB21",
"A6": "AA18",
"A9": "E3",
"A10": "N2",
"A11": "F3",
"A12": "P2",
"A15": "M2",
"A16": "L1",
"A17": "M3",
"A18": "M1",
"A21": "J6",
"A22": "D2",
"A23": "K6",
"A24": "E2",
"A27": "M5",
"A28": "L4",
"A29": "M6",
"A30": "L5",
"A33": "P4",
"A34": "N5",
"A35": "P5",
"A36": "P6",
"A39": "G4",
"A40": "G3",
"A41": "H4",
"A42": "H3",
"A45": "J4",
"A46": "K3",
"A47": "K4",
"A48": "L3",
"A51": "P1",
"A52": "N3",
"A53": "R1",
"A54": "N4",
"A57": "B2",
"A58": "A1",
"A59": "C2",
"A60": "B1",
"A63": "F1",
"A64": "D1",
"A65": "G1",
"A66": "E1",
"A69": "H5",
"A70": "G2",
"A71": "J5",
"A72": "H2",
"A75": "J1",
"A76": "J2",
"A77": "K1",
"A78": "K2",
},
),
Connector(
"top_c",
0,
{
"C29": "U18",
"C30": "Y1",
"C31": "U17",
"C32": "W1",
"C33": "V2",
"C34": "N14",
"C35": "U2",
"C36": "N13",
},
),
Connector(
"bottom_a",
0,
{
"A3": "AB1",
"A4": "AA3",
"A5": "AA1",
"A6": "Y3",
"A9": "D16",
"A10": "A16",
"A11": "E16",
"A12": "A15",
"A15": "A19",
"A16": "A21",
"A17": "A18",
"A18": "B21",
"A21": "C20",
"A22": "D21",
"A23": "D20",
"A24": "E21",
"A27": "B22",
"A28": "D22",
"A29": "C22",
"A30": "E22",
"A33": "B13",
"A34": "A14",
"A35": "C13",
"A36": "A13",
"A39": "C17",
"A40": "B18",
"A41": "D17",
"A42": "B17",
"A45": "C19",
"A46": "D19",
"A47": "C18",
"A48": "E19",
"A51": "F14",
"A52": "B16",
"A53": "F13",
"A54": "B15",
"A57": "E17",
"A58": "F20",
"A59": "F16",
"A60": "F19",
"A63": "E18",
"A64": "A20",
"A65": "F18",
"A66": "B20",
"A69": "G22",
"A70": "C15",
"A71": "G21",
"A72": "C14",
"A75": "D15",
"A76": "E14",
"A77": "D14",
"A78": "E13",
},
),
Connector(
"bottom_b",
0,
{
"B3": "Y2",
"B4": "AB6",
"B5": "W2",
"B6": "AB7",
"B9": "Y7",
"B10": "AB8",
"B11": "Y8",
"B12": "AA8",
"B15": "AA6",
"B16": "AB5",
"B17": "Y6",
"B18": "AA5",
"B21": "AB2",
"B22": "Y9",
"B23": "AB3",
"B24": "W9",
"B27": "T6",
"B28": "W7",
"B29": "R6",
"B30": "V7",
"B33": "V8",
"B34": "V5",
"B35": "V9",
"B36": "U6",
"B39": "W4",
"B40": "AA4",
"B41": "V4",
"B42": "Y4",
"B45": "T4",
"B46": "U5",
"B47": "R4",
"B48": "T5",
"B51": "E10",
"B52": "E6",
"B53": "F10",
"B54": "F6",
"B57": "C7",
"B58": "C11",
"B59": "D7",
"B60": "D11",
"B63": "A6",
"B64": "A10",
"B65": "B6",
"B66": "B10",
"B69": "C5",
"B70": "C9",
"B71": "D5",
"B72": "D9",
"B75": "A4",
"B76": "A8",
"B77": "B4",
"B78": "B8",
},
),
Connector(
"bottom_c",
0,
{
"C29": "U1",
"C30": "W5",
"C31": "T1",
"C32": "W6",
"C33": "R2",
"C34": "V3",
"C35": "R3",
"C36": "U3",
},
),
Connector(
"top_b",
0,
{
"B3": "R14",
"B4": "R16",
"B5": "P14",
"B6": "P15",
"B9": "R17",
"B10": "P17",
"B11": "P16",
"B12": "N17",
"B15": "W17",
"B16": "T18",
"B17": "V17",
"B18": "R18",
"B21": "AB20",
"B22": "V19",
"B23": "AA19",
"B24": "V18",
"B27": "Y19",
"B28": "V20",
"B29": "Y18",
"B30": "U20",
"B33": "AB10",
"B34": "AB15",
"B35": "AA9",
"B36": "AA15",
"B39": "W12",
"B40": "Y12",
"B41": "W11",
"B42": "Y11",
"B45": "V14",
"B46": "V15",
"B47": "V13",
"B48": "U15",
"B51": "W10",
"B52": "AB17",
"B53": "V10",
"B54": "AB16",
"B57": "AB12",
"B58": "AA16",
"B59": "AB11",
"B60": "Y16",
"B63": "AA11",
"B64": "T15",
"B65": "AA10",
"B66": "T14",
"B69": "AB13",
"B70": "Y14",
"B71": "AA13",
"B72": "W14",
"B75": "AA14",
"B76": "W16",
"B77": "Y13",
"B78": "W15",
},
),
]

def __init__(self, **kwargs):
super().__init__(**kwargs)

def toolchain_program(self, products, name):
(loader, bridge_bin) = find_loader()
with products.extract("{}.bin".format(name)) as bitstream_filename:
subprocess.check_call(
[loader, "-e", "-f", bitstream_filename, "-p", bridge_bin]
)


if __name__ == "__main__":
from .test.blinky import Blinky

AlchitryPtV2Platform().build(Blinky(), do_program=True)