humpback-dds/nmigen/humpback.py

323 lines
7.3 KiB
Python
Raw Normal View History

2020-08-07 13:39:43 +08:00
# Strongly inspired by the migen build of humpback
# Using STM32 Nucleo-H743ZI2 board
# Note to self: Pin assignment differs from Nucleo-H743ZI
import os
import subprocess
from nmigen.build import *
from nmigen.vendor.lattice_ice40 import *
from nmigen_boards.resources import *
from resources import *
__all__ = ["HumpbackPlatform"]
class HumpbackPlatform(LatticeICE40Platform):
device = "iCE40HX8K" # Using ICE40HX8K-CT256
package = "CT256"
2020-08-07 16:05:59 +08:00
default_clk = "clk25"
2020-08-07 13:39:43 +08:00
resources = [
# Define clock
Resource("clk25", 0, Pins("K9", dir="i"),
Clock(25e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")
),
# Define user LED
Resource("user_led", 0, Pins("H3", dir="o"),
Attrs(IO_STANDARD="SB_LVCMOS")
),
2020-08-07 17:16:56 +08:00
# TODO: Define UART interfaces somewhere else, make it optional
2020-08-07 13:39:43 +08:00
UARTResource(0,
rx="T11", tx="M13", rts="M15", cts="T10",
attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
),
# UART1 interface: Read note for UART interface above
# UART1 interface is broken due to pin rearrangement introduced for Nucleo-H743ZI2
# Uncomment if fixed, or found an alternative (e.g. bit banging UART)
# *UARTResource(1,
# tx="M11", rx="T13", rts="A6", cts="B16",
# attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
# ),
# Define SPI interfaces
2020-08-07 17:16:56 +08:00
# TODO; Make it optional, define it in a block
2020-08-07 13:39:43 +08:00
# Note: Use "role=device" to make humpback a SPI slave
# The ~CS pin is a global pin, but not being configured global.
SPIResource(0,
cs="R2", clk="C8", mosi="N5", miso="T2",
attrs=Attrs(IO_STANDARD="SB_LVCMOS")
),
# Define I2C interface
2020-08-07 17:16:56 +08:00
# TODO: Make it optional, declare it in a block itself
2020-08-07 13:39:43 +08:00
# Use "role=device" to make humpback a I2C slave
I2CResource(0,
sda="T16", scl="M12",
attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
),
]
2020-08-07 16:05:59 +08:00
# Using the dict approach in (o)migen
2020-08-07 16:32:44 +08:00
# Note: Numbering is required in nMigen, so some probably not very meaningful strings/integers are inserted
2020-08-07 16:05:59 +08:00
connectors = [
2020-08-07 16:32:44 +08:00
# EEM0 Connector
2020-08-07 16:05:59 +08:00
Connector("eem", 0, {
"d0_cc_n": "H1",
"d0_cc_p": "J3",
2020-08-07 21:22:41 +08:00
"d1_n" : "B1",
"d1_p" : "F5",
"d2_n" : "C2",
"d2_p" : "C1",
"d3_n" : "D2",
"d3_p" : "F4",
"d4_n" : "D1",
"d4_p" : "G5",
"d5_n" : "E3",
"d5_p" : "G4",
"d6_n" : "E2",
"d6_p" : "H5",
"d7_n" : "F3",
"d7_p" : "G3",
2020-08-07 16:05:59 +08:00
}),
2020-08-07 16:12:28 +08:00
2020-08-07 16:32:44 +08:00
# EEM1 Connector
2020-08-07 16:12:28 +08:00
Connector("eem", 1, {
2020-08-07 16:05:59 +08:00
"d0_cc_n": "L3",
"d0_cc_p": "L6",
"d1_n": "F1",
"d1_p": "H6",
"d2_n": "G2",
"d2_p": "H4",
"d3_n": "H2",
"d3_p": "J4",
"d4_n": "J1",
"d4_p": "J2",
"d5_n": "K3",
"d5_p": "K1",
"d6_n": "L1",
"d6_p": "L4",
"d7_n": "M1",
"d7_p": "K4",
}),
2020-08-07 16:32:44 +08:00
# EEM2 Connector
2020-08-07 16:12:28 +08:00
Connector("eem", 2, {
2020-08-07 21:26:18 +08:00
"d0_cc_n": "G1",
2020-08-07 16:05:59 +08:00
"d0_cc_p": "J5",
"d1_n": "M2",
"d1_p": "K5",
"d2_n": "N2",
"d2_p": "L7",
"d3_n": "M3",
"d3_p": "M6",
"d4_n": "N3",
"d4_p": "L5",
"d5_n": "M4",
"d5_p": "P1",
"d6_n": "M5",
"d6_p": "P2",
"d7_n": "N4",
"d7_p": "R1",
}),
2020-08-07 16:32:44 +08:00
# STM32 Nucleo/ Arduino Connector
2020-08-07 21:22:41 +08:00
# TODO: Suspect SPI mismatch forever
2020-08-07 16:32:44 +08:00
Connector("stm32", "pins", {
2020-08-07 21:22:41 +08:00
"PA0": "A2",
2020-08-07 17:40:06 +08:00
# "PA1": "P14", # PA1 -> PB2, but PB2 has a mapping on FPGA already
# "PA2": "B8", # PA2 -> PF6
2020-08-07 21:22:41 +08:00
"PA3": "L13",
"PA5": "C8",
"PA6": "T2",
2020-08-07 21:26:18 +08:00
# "PA7": "N12", # PA7 -> PE9, but PE9 has a mapping on FPGA already
# "PA8": "M9", # PA8 -> PF2
# "PA9": "P10", # PA9 -> PF1
# "PA10": "R10", # PA10 -> PF0
"PA15": "B14",
2020-08-07 16:05:59 +08:00
2020-08-07 21:26:18 +08:00
"PB0": "A1",
# "PB1": "G12", # PB1 -> PF4
"PB1": "M14", # PC1 -> PB1
"PB2": "B6",
"PB5": "N5",
# "PB6": "A7", # PB6 -> PG6
2020-08-07 17:40:06 +08:00
"PB6": "T13", # PG9 -> PB6
"PB7": "M11", # PG10 -> PB7
2020-08-07 21:26:18 +08:00
"PB8": "M12",
"PB9": "T16",
"PB10": "C3",
"PB11": "F7",
"PB12": "B13",
"PB13": "B12",
"PB15": "A11",
2020-08-07 16:05:59 +08:00
"PC0": "L14",
2020-08-07 17:40:06 +08:00
# "PC1": "M14", # PC1 -> PB1
# "PC2": "A9", # PC2 -> PF5
"PC2": "N16", # PC4 -> PC2
2020-08-07 16:05:59 +08:00
"PC3": "M16",
2020-08-07 17:40:06 +08:00
# "PC4": "N16", # PC4 -> PC2
# "PC5": "P16", # PC5 -> PF10
2020-08-07 16:05:59 +08:00
"PC6": "B10",
"PC7": "B15",
"PC8": "H16",
"PC9": "J10",
"PC10": "J16",
"PC11": "J15",
"PC12": "K12",
"PD0": "T9",
"PD1": "N9",
"PD2": "K13",
2020-08-07 17:16:56 +08:00
"PD3": "T10",
"PD4": "A6",
"PD5": "T11",
"PD6": "M13",
2020-08-07 16:05:59 +08:00
"PD7": "L12",
"PD11": "E5",
"PD12": "D5",
"PD13": "C5",
2020-08-07 17:16:56 +08:00
"PD14": "R2",
"PE0": "D3",
"PE2": "P15",
"PE3": "N10",
"PE4": "R15",
"PE5": "T15",
"PE6": "M8",
"PE7": "E6",
"PE8": "D6",
"PE9": "F12",
"PE10": "A5",
"PE11": "G11",
"PE12": "B4",
2020-08-07 17:40:06 +08:00
# "PE13": "F11", # PE13 -> PG12
# "PE14": "C4", # PE14 -> PE6, but PE6 has a mapping on FPGA already
"PE14": "B9", # PF14 -> PE14
2020-08-07 17:16:56 +08:00
"PE15": "B3",
2020-08-07 16:05:59 +08:00
2020-08-07 17:40:06 +08:00
"PF0": "R10", # PA10 -> PF0
"PF1": "P10", # PA9 -> PF1
"PF2": "M9", # PA8 -> PF2
"PF4": "G12", # PB1 -> PF4
"PF5": "A9", # PC2 -> PF5
"PF6": "B8", # PA2 -> PF6
2020-08-07 21:26:18 +08:00
"PF7": "L9",
2020-08-07 16:05:59 +08:00
"PF8": "L10",
"PF9": "P9",
2020-08-07 17:40:06 +08:00
"PF10": "P16", # PC5 -> PF10
# "PF14": "B9", # PF14 -> PE14
# "PF15": "B16", # PF15 -> PG14
2020-08-07 16:05:59 +08:00
"PG0": "M7",
"PG1": "P8",
"PG2": "K14",
"PG3": "K15",
2020-08-07 17:40:06 +08:00
"PG6": "A7", # PB6 -> PG6
# "PG9": "T13", # PG9 -> PB6
# "PG10": "M11", # PG10 -> PB7
"PG12": "F11", # PE13 -> PG12
"PG14": "B16", # PF15 -> PG14
2020-08-07 16:05:59 +08:00
}),
2020-08-07 16:32:44 +08:00
# Beaglebone Black Connector
Connector("bb", "pins", {
"CLKOUT": "R9",
"GPIO0_7": "R14",
"GPIO1_16": "A16",
"GPIO1_17": "R3",
"GPIO1_29": "D11",
"GPIO1_31": "D14",
"GPIO2_6": "D16",
"GPIO2_7": "C16",
"GPIO2_8": "E16",
"GPIO2_9": "D15",
"GPIO2_11": "F15",
"GPIO2_13": "F16",
"GPIO2_22": "C11",
"GPIO2_23": "C10",
"GPIO2_24": "E10",
"GPIO2_25": "D4",
"GPIO3_19": "P4",
"GPIO3_21": "R4",
2020-08-07 21:29:43 +08:00
"GPMC_A2": "T7",
2020-08-07 16:32:44 +08:00
"GPMC_A3": "T1",
2020-08-07 21:29:43 +08:00
"GPMC_A14": "F9",
"GPMC_A15": "B7",
"GPMC_AD0": "C12",
"GPMC_AD1": "E11",
"GPMC_AD2": "J12",
"GPMC_AD3": "J11",
"GPMC_AD4": "C13",
"GPMC_AD5": "C14",
"GPMC_AD6": "J14",
"GPMC_AD7": "J13",
"GPMC_AD8": "E13",
"GPMC_AD9": "G13",
"GPMC_AD10": "G14",
"GPMC_AD11": "G10",
"GPMC_AD12": "E14",
"GPMC_AD13": "H14",
"GPMC_AD14": "F14",
"GPMC_AD15": "F13",
"GPMC_ADVN": "H12",
"GPMC_BE0N": "G16",
"GPMC_CLK": "H11",
"GPMC_CSN1": "D13",
"GPMC_OEN": "H13",
"GPMC_WE1N": "G15",
2020-08-07 16:32:44 +08:00
}),
# ESP32 Connector
Connector("esp32", "pins", {
2020-08-07 21:29:43 +08:00
"IO2": "D9",
"IO4": "D7",
"IO22": "C7",
"IO34": "E9",
"IO35": "C9",
2020-08-07 16:32:44 +08:00
}),
# OrangePI Zero Connector
Connector("orange_pi", "pins", {
"PG06": "A15",
}),
2020-08-07 16:05:59 +08:00
]
2020-08-07 13:39:43 +08:00
2020-08-07 21:12:15 +08:00
eem_to_urukul = [
Resource("eem", 1,
Subsignal("sclk", DiffPairs("L6", "L3", dir="o", conn=("eem", 1))),
Subsignal("mosi", DiffPairs("H6", "F1", dir="o", conn=("eem", 1))),
Subsignal("miso", DiffPairs("H4", "G2", dir="i", conn=("eem", 1)),
Attrs(IO_STANDARD="SB_LVDS_INPUT")),
Subsignal("cs", DiffPairs("J4 J2 K1", "H2 J1 K3", dir="o", conn=("eem", 1))),
Subsignal("io_update", DiffPairs("L4", "L1", dir="o", conn=("eem", 1))),
Subsignal("sync_out", DiffPairs("K4", "M1", dir="o", conn=("emm", 1))),
2020-08-07 21:12:15 +08:00
Attrs(IO_STANDARD="SB_LVCMOS")
)
]
2020-08-07 13:39:43 +08:00
# tool chain setup, using default ICE40 HX8K evaluation code
def toolchain_program(self, products, name):
iceprog = os.environ.get("ICEPROG", "iceprog")
with products.extract("{}.bin".format(name)) as bitstream_filename:
subprocess.check_call([iceprog, "-S", bitstream_filename])
if __name__ == "__main__":
2020-08-07 21:12:15 +08:00
from nmigen_boards.test.blinky import *
platform = HumpbackPlatform()
platform.add_resources(platform.eem_to_urukul)
platform.build(Blinky(), do_program=False)
2020-08-07 13:39:43 +08:00