Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added XC6SLX16 PiSwords dev board #191

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
115 changes: 115 additions & 0 deletions amaranth_boards/colorlight_5a75b_r8_0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import os
import subprocess

from amaranth.build import *
from amaranth.vendor.lattice_ecp5 import *
from amaranth_boards.resources import *


__all__ = ["Colorlight_5A75B_R80Platform"]


class Colorlight_5A75B_R80Platform(LatticeECP5Platform):
device = "LFE5U-25F"
package = "BG256"
speed = "6"
default_clk = "clk25"

# Pins according to https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V8.0.md
# Some of these still need verifying.

resources = [
Resource("clk25", 0, Pins("P6", dir="i"), Clock(25e6), Attrs(IO_TYPE="LVCMOS33")),

*LEDResources(pins="T6", invert = True,
attrs=Attrs(IO_TYPE="LVCMOS33", DRIVE="4")),

*ButtonResources(pins="R7", invert = True,
attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")),

UARTResource(0,
tx="T6", # led (J19 DATA_LED-)
rx="R7", # btn (J19 KEY+)
attrs=Attrs(IO_TYPE="LVCMOS33")
),

# SPIFlash (25Q32JVSIQ) 32-Mbits
Resource("spi_flash", 0,
Subsignal("cs", PinsN("N8", dir="o")),
# Subsignal("clk", Pins("", dir="i")), # driven through USRMCLK
Subsignal("cipo", Pins("T8", dir="i")), # Chip: DI/IO0
Subsignal("copi", Pins("T7", dir="o")), # DO/IO1
# Subsignal("wp", PinsN("unknown", dir="o")), # IO2 Todo
# Subsignal("hold", PinsN("unknown", dir="o")), # IO3 Todo
Attrs(IO_TYPE="LVCMOS33")
),

# 1x ESMT M12L64322A 2M 200MHz SDRAM (organized as 4 x 512k x 32bit)
SDRAMResource(0,
clk="C8", we_n="B5", cas_n="A6", ras_n="B6",
ba="B7 A8", a="A9 B9 B10 C10 D9 C9 E9 D8 E8 C7 B8",
dq="B2 A2 C3 A3 B3 A4 B4 A5 E7 C6 D7 D6 E6 D5 C5 E5 "
"A11 B11 B12 A13 B13 A14 D14 D13 E11 C13 D11 C12 E10 C11 D10",
attrs=Attrs(PULLMODE="NONE", DRIVE="4", SLEWRATE="FAST", IO_TYPE="LVCMOS33")
),

# 2x Realtek RTL8211FD Gigabit Ethernet PHYs
Resource("eth_rgmii", 0,
Subsignal("rst", PinsN("R6", dir="o")),
Subsignal("mdc", Pins("R5", dir="o")),
Subsignal("mdio", Pins("T4", dir="io")),
Subsignal("tx_clk", Pins("L1", dir="o")),
Subsignal("tx_ctl", Pins("L2", dir="o")),
Subsignal("tx_data", Pins("M2 M1 P1 R1", dir="o")),
Subsignal("rx_clk", Pins("J1", dir="i")),
Subsignal("rx_ctl", Pins("J2", dir="i")),
Subsignal("rx_data", Pins("K2 J3 K1 K3", dir="i")),
Attrs(IO_TYPE="LVCMOS33")
),

Resource("eth_rgmii", 1,
Subsignal("rst", PinsN("R6", dir="o")),
Subsignal("mdc", Pins("R5", dir="o")),
Subsignal("mdio", Pins("T4", dir="io")),
Subsignal("tx_clk", Pins("J16", dir="o")),
Subsignal("tx_ctl", Pins("K14", dir="o")),
Subsignal("tx_data", Pins("K16 J15 J14 K15", dir="o")),
Subsignal("rx_clk", Pins("M16", dir="i")),
Subsignal("rx_ctl", Pins("P16", dir="i")),
Subsignal("rx_data", Pins("M15 R16 L15 L16", dir="i")),
Attrs(IO_TYPE="LVCMOS33")
),

]
connectors = [
Connector("j", 1, "C4 D4 E4 - D3 F5 E3 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 2, "F1 F2 G2 - G1 H2 H3 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 3, "B1 C2 C1 - D1 E2 E1 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 4, "P5 R3 P2 - R2 T2 N6 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 5, "T13 R12 R13 - R14 T14 P12 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 6, "R15 T15 P13 - P14 N14 H15 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 7, "G16 H14 G15 - F15 F16 E16 N4 N5 N3 P3 P4 M3 N1 M4 -"),
Connector("j", 8, "D16 E15 C16 - B16 C15 B15 N4 N5 N3 P3 P4 M3 N1 M4 -"),
#Connector("j", 19, " - M13 - - P11"),
]

@property
def required_tools(self):
return super().required_tools + [
"openFPGALoader"
]

def toolchain_prepare(self, fragment, name, **kwargs):
overrides = dict(ecppack_opts="--compress")
overrides.update(kwargs)
return super().toolchain_prepare(fragment, name, **overrides)

def toolchain_program(self, products, name):
tool = os.environ.get("OPENFPGALOADER", "openFPGALoader")
with products.extract("{}.bit".format(name)) as bitstream_filename:
subprocess.check_call([tool, "-c", "ft232", "-m", bitstream_filename])


if __name__ == "__main__":
from .test.blinky import *
Colorlight_5A75B_R80Platform().build(Blinky(), do_program=True)
131 changes: 131 additions & 0 deletions amaranth_boards/pislx16.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env python3

import os
import subprocess

from amaranth.build import *
from amaranth.vendor.xilinx_spartan_3_6 import *
from amaranth_boards.resources import *

__all__ = ["PiSLX16Platform"]

"""
http://piswords.com/xc6slx16.html

Xilinx spartan6 XC6SLX16 Core Board Xilinx spartan 6 FPGA development board with 256mbit SDRAM

Useful notes on getting the openocd interface working :

https://tomverbeure.github.io/2019/09/15/Loading-a-Spartan-6-bitstream-with-openocd.html
"""

class PiSLX16Platform(XilinxSpartan6Platform):
device = "xc6slx16"
package = "ftg256"
speed = "3"
default_clk = "clk50"
resources = [
Resource("clk50", 0, Pins("T8", dir="i"),
Clock(50e6), Attrs(IOSTANDARD="LVCMOS33")),

# 4 Blue LEDs, LED0 .. LED3
*LEDResources(pins="P4 N5 P5 M6", attrs=Attrs(IOSTANDARD="LVCMOS33")),

# RESET key is L3 (all keys have pull-ups onboard)
*ButtonResources(pins="C3 D3 E4 E3 L3", attrs=Attrs(IOSTANDARD="LVCMOS33")),

# SPI Flash M25P16
*SPIFlashResources(0,
cs_n="T3", clk="R11", copi="T10", cipo="P10", attrs=Attrs(IOSTANDARD="LVCMOS33")
),

# UART CH340C
UARTResource(0, rx="C11", tx="D12", attrs=Attrs(IOSTANDARD="LVCMOS33")),

# DRAM H57V2562GTR SDRAMResource TODO
# I2C AT24C02 EEPROM I2CResource TODO
# SDCardResources
Resource("sd_clk", 0, Pins("M3", dir="o")),
Resource("sd_di", 0, Pins("L5", dir="o")),
Resource("sd_do", 0, Pins("L4", dir="i")),
Resource("sd_cs", 0, Pins("N3", dir="o")),
]
connectors = [
Connector("p", 1,
"- - K16 J16 L16 K15 M15 M16 P16 N16 "
"R16 P15 T15 R15 T14 R14 R12 T13 R9 T12 "
"L8 T9 R7 T7 T5 T6 T4 R5 R1 R2 "
"P2 M4 P6 N6 M5 N4 - - - - "
),
Connector("p", 2,
"- - A4 B5 A5 B6 A6 A7 B8 A8 "
"C8 A9 A10 B10 A11 A12 B12 A13 A14 B14 "
"B15 B16 C15 C16 D16 E15 C9 E11 C10 D11 "
"E16 F15 F16 G16 H15 H16 - - - - "
),
]

# Programming using openocd (programs FPGA's volatile config)

@property
def file_templates(self):
return {
**super().file_templates,
"{{name}}-openocd.cfg": "adapter_khz 8000",
}

def toolchain_program_open_ocd(self, products, name, config=None, **kwargs):
openocd = os.environ.get("OPENOCD", "openocd")
with products.extract(f"{name}-openocd.cfg", f"{name}.bit") \
as (config_filename, vector_filename):
cmd = ";".join([
"transport select jtag",
"init",
"xc6s_program xc6s.tap",
f"pld load 0 {vector_filename}",
"exit",
])
subprocess.check_call([openocd,
"-f", config,
"-f", "cpld/xilinx-xc6s.cfg",
"-f", config_filename,
"-c", cmd,
])

# Programming using openFPGALoader (SPI flash)

def toolchain_program_open_fpga_loader(self, products, name, config=None, addr=None, dev=None, **kwargs):
with products.extract(f"{name}.bit") as filename:
conf = config or "digilent_hs3"
cmd = [
"openFPGALoader",
"--fpga-part", self.device + self.package, # "xc6slx16ftg256",
"-c", conf,
filename,
]
if addr is not None:
cmd += [ "-f", "-o", str(addr) ]
if dev is not None:
cmd += [ "-d", dev ]

subprocess.check_call(cmd)

# Programming (default to using Digilent JTAG-HS3)
def toolchain_program(self, products, name, **kwargs):
if kwargs.get("openocd"):
config = kwargs.get("config", "interface/ftdi/digilent_jtag_hs3.cfg")
self.toolchain_program_open_ocd(products, name, config=config)
else:
self.toolchain_program_open_fpga_loader(products, name, **kwargs)


if __name__ == "__main__":
from amaranth_boards.test.blinky import Blinky
dut = Blinky()
opts = {
#"openocd" : True,
"config" : "digilent_hs3", # default
"addr" : 0, # write to flash at this offset
}
PiSLX16Platform().build(dut, do_program=True, program_opts=opts, verbose=True)