summaryrefslogtreecommitdiff
path: root/platform_alchitry_pt_v2.py
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2025-08-29 21:14:32 +0200
committerYuval Adam <_@yuv.al>2025-08-29 21:14:32 +0200
commit47cd3f14cc120567cf290135a2966c71344a4a5f (patch)
tree9b82835055af3727a78f63955bcb94d08bbcb15a /platform_alchitry_pt_v2.py
parent7f955d1f07ffb99b93378c41418434aa26075e5f (diff)
Full board def from upstream
Diffstat (limited to 'platform_alchitry_pt_v2.py')
-rw-r--r--platform_alchitry_pt_v2.py934
1 files changed, 431 insertions, 503 deletions
diff --git a/platform_alchitry_pt_v2.py b/platform_alchitry_pt_v2.py
index 9837f0b..235b61f 100644
--- a/platform_alchitry_pt_v2.py
+++ b/platform_alchitry_pt_v2.py
@@ -1,4 +1,7 @@
-from amaranth.build import Resource, Pins, Attrs, Clock, DiffPairs
+import os
+import subprocess
+
+from amaranth.build import Resource, Pins, Attrs, Clock, DiffPairs, Subsignal, Connector
from amaranth.vendor import XilinxPlatform
@@ -6,9 +9,9 @@ __all__ = ["AlchitryPtV2Platform"]
# 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
-# https://github.com/alchitry/Alchitry-Labs-V2/blob/master/src/main/kotlin/com/alchitry/labs2/hardware/pinout/PtV2TopPin.kt
class AlchitryPtV2Platform(XilinxPlatform):
@@ -18,7 +21,6 @@ class AlchitryPtV2Platform(XilinxPlatform):
default_clk = "clk100"
resources = [
- # 100MHz clock - official pin from Alchitry Labs
Resource(
"clk100",
0,
@@ -26,9 +28,7 @@ class AlchitryPtV2Platform(XilinxPlatform):
Clock(100e6),
Attrs(IOSTANDARD="LVCMOS33"),
),
- # Reset button - official pin from Alchitry Labs
Resource("rst_n", 0, Pins("N15", dir="i"), Attrs(IOSTANDARD="LVCMOS33")),
- # LEDs - official pins from Alchitry Labs
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")),
@@ -37,515 +37,443 @@ class AlchitryPtV2Platform(XilinxPlatform):
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",
+ 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(
+ "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")),
+ # DDR3 SDRAM
+ Resource(
+ "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"),
+ ),
]
- # Helper function to add a range of IO resources
- def _add_io_resources(self, prefix, start_idx, pins_dict, io_standard="LVCMOS33"):
- for name, fpga_pin in pins_dict.items():
- # Adjust index for sequential numbering starting from start_idx
- # We assume 'A3', 'A4', 'A5', etc., implies an underlying sequential numbering
- # If the original labels are important, you might use them as sub-identifiers
- # For simplicity, I'm assigning sequential indices based on iteration order.
- # You might want to map 'A3' to index 3 if that's preferred.
- self.resources.append(
- Resource(
- "io_{}{}".format(prefix, name.lower()),
- 0, # Index 0 since we're using the full name as unique identifier
- Pins(fpga_pin, dir="io"),
- Attrs(IOSTANDARD=io_standard),
- )
- )
-
- def __init__(self):
- super().__init__()
-
- # --- Top Side Pins (PtV2AlphaTopPin and PtV2TopPin are identical for these banks) ---
- # A Bank Pins (Top Side)
- top_a_pins = {
- "A3": "AB22",
- "A5": "AB21",
- "A9": "E3",
- "A11": "F3",
- "A15": "M2",
- "A17": "M3",
- "A21": "J6",
- "A23": "K6",
- "A27": "M5",
- "A29": "M6",
- "A33": "P4",
- "A35": "P5",
- "A39": "G4",
- "A41": "H4",
- "A45": "J4",
- "A47": "K4",
- "A51": "P1",
- "A53": "R1",
- "A57": "B2",
- "A59": "C2",
- "A63": "F1",
- "A65": "G1",
- "A69": "H5",
- "A71": "J5",
- "A75": "J1",
- "A77": "K1",
- "A4": "AB18",
- "A6": "AA18",
- "A10": "N2",
- "A12": "P2",
- "A16": "L1",
- "A18": "M1",
- "A22": "D2",
- "A24": "E2",
- "A28": "L4",
- "A30": "L5",
- "A34": "N5",
- "A36": "P6",
- "A40": "G3",
- "A42": "H3",
- "A46": "K3",
- "A48": "L3",
- "A52": "N3",
- "A54": "N4",
- "A58": "A1",
- "A60": "B1",
- "A64": "D1",
- "A66": "E1",
- "A70": "G2",
- "A72": "H2",
- "A76": "J2",
- "A78": "K2",
- }
- for i, (name, pin) in enumerate(top_a_pins.items()):
- self.resources.append(
- Resource(
- "io_top_a", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
-
- # B Bank Pins (PtV2AlphaTopPin vs PtV2TopPin has differences here)
- # Using PtV2TopPin for consistency with the example and it seems more generic for V2
- top_b_pins = {
- "B3": "R14",
- "B5": "P14",
- "B9": "R17",
- "B11": "P16",
- "B15": "W17",
- "B17": "V17",
- "B21": "AB20",
- "B23": "AA19",
- "B27": "Y19",
- "B29": "Y18",
- "B33": "AB10",
- "B35": "AA9",
- "B39": "W12",
- "B41": "W11",
- "B45": "V14",
- "B47": "V13",
- "B51": "W10",
- "B53": "V10",
- "B57": "AB12",
- "B59": "AB11",
- "B63": "AA11",
- "B65": "AA10",
- "B69": "AB13",
- "B71": "AA13",
- "B75": "AA14",
- "B77": "Y13",
- "B4": "R16",
- "B6": "P15",
- "B10": "P17",
- "B12": "N17",
- "B16": "T18",
- "B18": "R18",
- "B22": "V19",
- "B24": "V18",
- "B28": "V20",
- "B30": "U20",
- "B34": "AB15",
- "B36": "AA15",
- "B40": "Y12",
- "B42": "Y11",
- "B46": "V15",
- "B48": "U15",
- "B52": "AB17",
- "B54": "AB16",
- "B58": "AA16",
- "B60": "Y16",
- "B64": "T15",
- "B66": "T14",
- "B70": "Y14",
- "B72": "W14",
- "B76": "W16",
- "B78": "W15",
- }
- for i, (name, pin) in enumerate(top_b_pins.items()):
- self.resources.append(
- Resource(
- "io_top_b", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
-
- # C Bank Pins (Top Side)
- top_c_pins = {
- "C29": "U18",
- "C31": "U17",
- "C33": "V2",
- "C35": "U2",
- "C30": "Y1",
- "C32": "W1",
- "C34": "N14",
- "C36": "N13",
- }
- for i, (name, pin) in enumerate(top_c_pins.items()):
- self.resources.append(
- Resource(
- "io_top_c", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
-
- # --- Bottom Side Pins (PtV2BottomPin) ---
- # A Bank Pins (Bottom Side)
- bottom_a_pins = {
- "A3": "AB1",
- "A5": "AA1",
- "A9": "D16",
- "A11": "E16",
- "A15": "A19",
- "A17": "A18",
- "A21": "C20",
- "A23": "D20",
- "A27": "B22",
- "A29": "C22",
- "A33": "B13",
- "A35": "C13",
- "A39": "C17",
- "A41": "D17",
- "A45": "C19",
- "A47": "C18",
- "A51": "F14",
- "A53": "F13",
- "A57": "E17",
- "A59": "F16",
- "A63": "E18",
- "A65": "F18",
- "A69": "G22",
- "A71": "G21",
- "A75": "D15",
- "A77": "D14",
- "A4": "AA3",
- "A6": "Y3",
- "A10": "A16",
- "A12": "A15",
- "A16": "A21",
- "A18": "B21",
- "A22": "D21",
- "A24": "E21",
- "A28": "D22",
- "A30": "E22",
- "A34": "A14",
- "A36": "A13",
- "A40": "B18",
- "A42": "B17",
- "A46": "D19",
- "A48": "E19",
- "A52": "B16",
- "A54": "B15",
- "A58": "F20",
- "A60": "F19",
- "A64": "A20",
- "A66": "B20",
- "A70": "C15",
- "A72": "C14",
- "A76": "E14",
- "A78": "E13",
- }
- for i, (name, pin) in enumerate(bottom_a_pins.items()):
- self.resources.append(
- Resource(
- "io_bottom_a", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
+ # --- IO Connectors ---
+ # Note on IOSTANDARD:
+ # Bank 13 can be powered by 3.3V, 2.5V, or 1.8V.
+ # All other IO banks (14, 16, 34, 35) are fixed at 3.3V.
+ # Defaulting to LVCMOS33 is safe, but for Bank 13, you may need to
+ # override the IOSTANDARD for your specific application if using a different VCC.
- # B Bank Pins (Bottom Side)
- bottom_b_pins = {
- "B3": "Y2",
- "B5": "W2",
- "B9": "Y7",
- "B11": "Y8",
- "B15": "AA6",
- "B17": "Y6",
- "B21": "AB2",
- "B23": "AB3",
- "B27": "T6",
- "B29": "R6",
- "B33": "V8",
- "B35": "V9",
- "B39": "W4",
- "B41": "V4",
- "B45": "T4",
- "B47": "R4",
- "B51": "E10",
- "B53": "F10",
- "B57": "C7",
- "B59": "D7",
- "B63": "A6",
- "B65": "B6",
- "B69": "C5",
- "B71": "D5",
- "B75": "A4",
- "B77": "B4",
- "B4": "AB6",
- "B6": "AB7",
- "B10": "AB8",
- "B12": "AA8",
- "B16": "AB5",
- "B18": "AA5",
- "B22": "Y9",
- "B24": "W9",
- "B28": "W7",
- "B30": "V7",
- "B34": "V5",
- "B36": "U6",
- "B40": "AA4",
- "B42": "Y4",
- "B46": "U5",
- "B48": "T5",
- "B52": "E6",
- "B54": "F6",
- "B58": "C11",
- "B60": "D11",
- "B64": "A10",
- "B66": "B10",
- "B70": "C9",
- "B72": "D9",
- "B76": "A8",
- "B78": "B8",
- }
- for i, (name, pin) in enumerate(bottom_b_pins.items()):
- self.resources.append(
- Resource(
- "io_bottom_b", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
-
- # C Bank Pins (Bottom Side)
- bottom_c_pins = {
- "C29": "U1",
- "C31": "T1",
- "C33": "R2",
- "C35": "R3",
- "C30": "W5",
- "C32": "W6",
- "C34": "V3",
- "C36": "U3",
- }
- for i, (name, pin) in enumerate(bottom_c_pins.items()):
- self.resources.append(
- Resource(
- "io_bottom_c", i, Pins(pin, dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- )
- )
-
- # --- Dedicated Peripherals (from PtV2TopPin as it contains more) ---
+ 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",
+ },
+ ),
+ ]
- # USB Controller
- self.resources.extend(
- [
- Resource(
- "usb_rx", 0, Pins("AA20", dir="i"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_tx", 0, Pins("AA21", dir="o"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 2, Pins("W21", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 3, Pins("W22", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 4, Pins("Y21", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 5, Pins("Y22", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 6, Pins("F15", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_d", 7, Pins("U7", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_rxf", 0, Pins("F21", dir="i"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_txe", 0, Pins("T3", dir="i"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_rd", 0, Pins("T16", dir="o"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_wr", 0, Pins("U16", dir="o"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "usb_siwui", 0, Pins("Y17", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- ]
- )
+ # The Top B connector differs between the Alpha and final V2 release.
+ # We handle this by dynamically adding the correct connector based on the revision.
+ _top_b_pins_v2 = {
+ "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",
+ }
- # SPI Flash
- self.resources.extend(
- [
- Resource(
- "spi_d", 0, Pins("P22", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "spi_d", 1, Pins("R22", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "spi_d", 2, Pins("P21", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "spi_d", 3, Pins("R21", dir="io"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- Resource(
- "spi_sck", 0, Pins("L12", dir="o"), Attrs(IOSTANDARD="LVCMOS33")
- ), # Bank 0, but usually has special IOSTANDARD
- Resource(
- "spi_ss", 0, Pins("T19", dir="o"), Attrs(IOSTANDARD="LVCMOS33")
- ),
- ]
- )
+ _top_b_pins_alpha = {
+ "B3": "AB13",
+ "B4": "AA11",
+ "B5": "AA13",
+ "B6": "AA10",
+ "B9": "AB12",
+ "B10": "Y14",
+ "B11": "AB11",
+ "B12": "W14",
+ "B15": "AB15",
+ "B16": "W16",
+ "B17": "AA15",
+ "B18": "W15",
+ "B21": "AB17",
+ "B22": "V19",
+ "B23": "AB16",
+ "B24": "V18",
+ "B27": "Y19",
+ "B28": "V20",
+ "B29": "Y18",
+ "B30": "U20",
+ "B33": "AB10",
+ "B34": "W10",
+ "B35": "AA9",
+ "B36": "V10",
+ "B39": "W12",
+ "B40": "Y12",
+ "B41": "W11",
+ "B42": "Y11",
+ "B45": "V14",
+ "B46": "V15",
+ "B47": "V13",
+ "B48": "U15",
+ "B51": "AB20",
+ "B52": "AA16",
+ "B53": "AA19",
+ "B54": "Y16",
+ "B57": "W17",
+ "B58": "T15",
+ "B59": "V17",
+ "B60": "T14",
+ "B63": "AA14",
+ "B64": "R16",
+ "B65": "Y13",
+ "B66": "P15",
+ "B69": "R17",
+ "B70": "T18",
+ "B71": "P16",
+ "B72": "R18",
+ "B75": "N14",
+ "B76": "P17",
+ "B77": "N13",
+ "B78": "N17",
+ }
- # DDR3 SDRAM - These generally require specific IO standards (SSTL135 for DDR3)
- # Note: Pin types (DQ, DQS, DM, A, BA, etc.) are crucial for memory interfaces.
- # Amaranth's build system supports complex memory resource definitions.
- # This is a simplified representation. For full DDR functionality, you'd
- # likely use a dedicated memory controller in your design.
- ddr_attrs = Attrs(
- IOSTANDARD="SSTL135_R",
- SLEW="FAST", # Commonly used for DDR IO
- DIFF_TERM="TRUE",
- ) # Differential termination for DQS
- ddr_ck_attrs = Attrs(
- IOSTANDARD="DIFF_SSTL135_R", DIFF_TERM="TRUE"
- ) # Differential clock
- ddr_ctrl_attrs = Attrs(IOSTANDARD="SSTL135_R", SLEW="FAST")
+ def __init__(self, *, revision="v2", **kwargs):
+ if revision.lower() == "v2":
+ self.connectors.append(Connector("top_b", 0, self._top_b_pins_v2))
+ elif revision.lower() in ("pt_alpha", "alpha"):
+ self.connectors.append(Connector("top_b", 0, self._top_b_pins_alpha))
+ else:
+ raise ValueError(f"Unknown revision '{revision}', expected 'v2' or 'alpha'")
+ super().__init__(**kwargs)
- # Data Group 0
- for i in range(8):
- self.resources.append(
- Resource(
- "ddr_dq",
- i,
- Pins(f"DDR_DQ{i}", dir="io", conn=("ddr", 0)),
- ddr_attrs,
- )
- )
- self.resources.extend(
- [
- Resource("ddr_dqs", 0, DiffPairs("K21", "K22", dir="io"), ddr_attrs),
- Resource("ddr_dm", 0, Pins("H22", dir="o"), ddr_attrs),
- ]
- )
+ def toolchain_program(self, products, name):
+ # Assumes Vivado is in the system's PATH
+ vivado_path = "vivado"
+ build_dir = products.get_dir()
- # Data Group 1
- for i in range(8, 16):
- self.resources.append(
- Resource(
- "ddr_dq",
- i,
- Pins(f"DDR_DQ{i}", dir="io", conn=("ddr", 1)),
- ddr_attrs,
- )
+ with products.extract(f"{name}.bit") as bitstream_filename:
+ tcl_script = os.path.join(build_dir, "program.tcl")
+ with open(tcl_script, "w") as f:
+ f.write(f"""
+# Vivado Tcl script for programming the Alchitry Pt
+open_hw_manager
+connect_hw_server -quiet
+open_hw_target
+current_hw_device [get_hw_devices xc7a100t_0]
+set_property PROGRAM.FILE {{{os.path.abspath(bitstream_filename)}}} [current_hw_device]
+program_hw_devices [current_hw_device]
+close_hw_target
+close_hw_server
+""")
+ subprocess.check_call(
+ [vivado_path, "-mode", "batch", "-source", tcl_script]
)
- self.resources.extend(
- [
- Resource("ddr_dqs", 1, DiffPairs("J14", "H14", dir="io"), ddr_attrs),
- Resource("ddr_dm", 1, Pins("G13", dir="o"), ddr_attrs),
- ]
- )
-
- # Control and Address
- self.resources.extend(
- [
- Resource("ddr_odt", 0, Pins("M17", dir="o"), ddr_ctrl_attrs),
- Resource(
- "ddr_reset_n", 0, Pins("J19", dir="o"), ddr_ctrl_attrs
- ), # Active low reset
- Resource("ddr_ba", 0, Pins("K19", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_ba", 1, Pins("N20", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_ba", 2, Pins("M20", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_ck", 0, DiffPairs("K17", "J17", dir="o"), ddr_ck_attrs),
- Resource("ddr_cke", 0, Pins("M22", dir="o"), ddr_ctrl_attrs),
- Resource(
- "ddr_cs_n", 0, Pins("N19", dir="o"), ddr_ctrl_attrs
- ), # Active low chip select
- Resource(
- "ddr_ras_n", 0, Pins("L20", dir="o"), ddr_ctrl_attrs
- ), # Active low RAS
- Resource(
- "ddr_cas_n", 0, Pins("N22", dir="o"), ddr_ctrl_attrs
- ), # Active low CAS
- Resource(
- "ddr_we_n", 0, Pins("L19", dir="o"), ddr_ctrl_attrs
- ), # Active low WE
- Resource("ddr_a", 0, Pins("K14", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 1, Pins("M15", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 2, Pins("N18", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 3, Pins("K16", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 4, Pins("L14", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 5, Pins("K18", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 6, Pins("M13", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 7, Pins("L18", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 8, Pins("L13", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 9, Pins("M18", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 10, Pins("K13", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 11, Pins("L15", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 12, Pins("M16", dir="o"), ddr_ctrl_attrs),
- Resource("ddr_a", 13, Pins("L16", dir="o"), ddr_ctrl_attrs),
- ]
- )
- # Analog Pins (usually 0V/1.35V reference, not standard digital IO)
- self.resources.extend(
- [
- Resource("vp", 0, Pins("L10", dir="i")), # Voltage Positive Reference
- Resource("vn", 0, Pins("M9", dir="i")), # Voltage Negative Reference
- ]
- )
- # Connectors for general purpose IO
- # These are now effectively covered by the _add_io_resources calls,
- # but you might want explicit connector definitions if you use them
- # in a structured way (e.g., "Pmod connector 0", "Header J1")
- # For now, the individually named io_top_a, io_bottom_b, etc., are more granular.
- self.connectors = [] # Keeping it empty as granular definitions are better
+if __name__ == "__main__":
+ # Example usage:
+ p = AlchitryPtV2Platform()
+ # To use the alpha board revision:
+ # p = AlchitryPtV2Platform(revision="alpha")
- def toolchain_program(self, products, name, **kwargs):
- import subprocess
- import os
+ # Requesting a single LED
+ led = p.request("led", 0)
+ print(f"LED 0: {led.pins}")
- with products.extract("{}.bit".format(name)) as bitstream_filename:
- tcl_content = f"""
-open_hw_manager
-connect_hw_server
-open_hw_target
-set_property PROGRAM.FILE {{{bitstream_filename}}} [get_hw_devices xc7a100t_0]
-set_property PROBES.FILE {{}} [get_hw_devices xc7a100t_0]
-set_property FULL_PROBES.FILE {{}} [get_hw_devices xc7a100t_0]
-current_hw_device [get_hw_devices xc7a100t_0]
-program_hw_devices [get_hw_devices xc7a100t_0]
-close_hw_manager
-exit
-"""
- tcl_script = "program_fpga.tcl"
- tcl_full_path = os.path.join("build", tcl_script)
- with open(tcl_full_path, "w") as f:
- f.write(tcl_content)
+ # Requesting a pin from a connector by name
+ a3_pin = p.request("top_a", conn_name="A3")
+ print(f"Top A3 pin: {a3_pin.pins}")
- subprocess.run(
- ["vivado", "-mode", "batch", "-source", tcl_script],
- cwd="build",
- check=True,
- )
+ # Requesting the DDR resource and accessing a subsignal
+ ddr = p.request("ddr3")
+ print(f"DDR DQS0 (p): {ddr.dqs.p[0].pin}")
+ print(f"DDR DQS0 (n): {ddr.dqs.n[0].pin}")