133 lines
4.6 KiB
Python
133 lines
4.6 KiB
Python
import os
|
|
import subprocess
|
|
import shutil
|
|
|
|
from amaranth.build import *
|
|
from amaranth.vendor.lattice_ecp5 import *
|
|
from .resources import *
|
|
|
|
|
|
__all__ = ["OrangeCrabR0_2Platform"]
|
|
|
|
|
|
class OrangeCrabR0_2Platform(LatticeECP5Platform):
|
|
device = "LFE5U-25F"
|
|
package = "MG285"
|
|
speed = "8"
|
|
default_clk = "clk"
|
|
resources = [
|
|
Resource("clk", 0, Pins("A9", dir="i"),
|
|
Clock(48e6), Attrs(IO_TYPE="LVCMOS33")),
|
|
|
|
# Used to reload FPGA configuration.
|
|
# Can enter USB bootloader by assigning button 0 to program.
|
|
Resource("program", 0, PinsN("V17", dir="o"), Attrs(IO_TYPE="LVCMOS33")),
|
|
|
|
RGBLEDResource(0,
|
|
r="K4", g="M3", b="J3", invert=True,
|
|
attrs=Attrs(IO_TYPE="LVCMOS33")),
|
|
|
|
*ButtonResources(
|
|
pins={0: "J17" }, invert=True,
|
|
attrs=Attrs(IO_TYPE="SSTL135_I")),
|
|
|
|
*SPIFlashResources(0,
|
|
cs_n="U17", clk="U16", cipo="T18", copi="U18", wp_n="R18", hold_n="N18",
|
|
attrs=Attrs(IO_TYPE="LVCMOS33"),
|
|
),
|
|
|
|
Resource("ddr3", 0,
|
|
Subsignal("rst", PinsN("L18", dir="o")),
|
|
Subsignal("clk", DiffPairs("J18", "K18", dir="o"), Attrs(IO_TYPE="SSTL135D_I")),
|
|
Subsignal("clk_en", Pins("D18", dir="o")),
|
|
Subsignal("cs", PinsN("A12", dir="o")),
|
|
Subsignal("we", PinsN("B12", dir="o")),
|
|
Subsignal("ras", PinsN("C12", dir="o")),
|
|
Subsignal("cas", PinsN("D13", dir="o")),
|
|
Subsignal("a", Pins("C4 D2 D3 A3 A4 D4 C3 B2 B1 D1 A7 C2 B6 C1 A2 C7", dir="o")),
|
|
Subsignal("ba", Pins("P5 N3 M3", dir="o")),
|
|
Subsignal("dqs", DiffPairs("G18 H17", "B15 A16", dir="io"),
|
|
Attrs(IO_TYPE="SSTL135D_I", TERMINATION="OFF",
|
|
DIFFRESISTOR="100")),
|
|
Subsignal("dq", Pins("C17 D15 B17 C16 A15 B13 A17 A13 F17 F16 G15 F15 J16 C18 H16 F18",
|
|
dir="io"), Attrs(TERMINATION="75")),
|
|
Subsignal("dm", Pins("G16 D16", dir="o")),
|
|
Subsignal("odt", Pins("C13", dir="o")),
|
|
Attrs(IO_TYPE="SSTL135_I", SLEWRATE="FAST")
|
|
),
|
|
|
|
Resource("ddr3_pseudo_power", 0,
|
|
# pseudo power pins, leave these at their default value
|
|
Subsignal("vcc_virtual", PinsN("K16 D17 K15 K17 B18 C6", dir="o")),
|
|
Subsignal("gnd_virtual", Pins("L15 L16", dir="o")),
|
|
Attrs(IO_TYPE="SSTL135_II", SLEWRATE="FAST")
|
|
),
|
|
|
|
Resource("adc", 0,
|
|
Subsignal("ctrl", Pins("G1 F1", dir="o")),
|
|
Subsignal("mux", Pins("F4 F3 F2 H1", dir="o")),
|
|
Subsignal("sense", DiffPairs("H3", "G3", dir="i"), Attrs(IO_TYPE="LVCMOS33D")),
|
|
Attrs(IO_TYPE="LVCMOS33")
|
|
),
|
|
|
|
*SDCardResources(0,
|
|
dat0="J1", dat1="K3", dat2="L3", dat3="M1", clk="K1", cmd="K2", cd="L1",
|
|
attrs=Attrs(IO_TYPE="LVCMOS33", SLEWRATE="FAST")
|
|
),
|
|
|
|
DirectUSBResource(0, d_p="N1", d_n="M2", pullup="N2", attrs=Attrs(IO_TYPE="LVCMOS33"))
|
|
]
|
|
connectors = [
|
|
Connector("io", 0, {
|
|
"0": "N17",
|
|
"1": "M18",
|
|
"5": "B10",
|
|
"6": "B9",
|
|
"9": "C8",
|
|
"10": "B8",
|
|
"11": "A8",
|
|
"12": "H2",
|
|
"13": "J2",
|
|
"a0": "L4",
|
|
"a1": "N3",
|
|
"a2": "N4",
|
|
"a3": "H4",
|
|
"a4": "G4",
|
|
"cipo": "N15",
|
|
"copi": "N16",
|
|
"sck": "R17",
|
|
"scl": "C9",
|
|
"sda": "C10"
|
|
})
|
|
]
|
|
|
|
@property
|
|
def required_tools(self):
|
|
return super().required_tools + [
|
|
"dfu-suffix"
|
|
]
|
|
|
|
@property
|
|
def command_templates(self):
|
|
return super().command_templates + [
|
|
r"""
|
|
{{invoke_tool("dfu-suffix")}}
|
|
-v 1209 -p 5af0 -a {{name}}.bit
|
|
"""
|
|
]
|
|
|
|
def toolchain_prepare(self, fragment, name, **kwargs):
|
|
overrides = dict(ecppack_opts="--compress --freq 38.8")
|
|
overrides.update(kwargs)
|
|
return super().toolchain_prepare(fragment, name, **overrides)
|
|
|
|
def toolchain_program(self, products, name):
|
|
dfu_util = os.environ.get("DFU_UTIL", "dfu-util")
|
|
with products.extract("{}.bit".format(name)) as bitstream_filename:
|
|
subprocess.check_call([dfu_util, "-D", bitstream_filename])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from .test.blinky import *
|
|
OrangeCrabR0_2Platform().build(Blinky(), do_program=True)
|