Skip to content

Commit f50d90f

Browse files

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

amaranth_boards/logicbone.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import os
2+
import subprocess
3+
4+
from amaranth.build import *
5+
from amaranth.vendor.lattice_ecp5 import *
6+
from .resources import *
7+
8+
9+
__all__ = ["LogicbonePlatform", "Logicbone85FPlatform"]
10+
11+
12+
class LogicbonePlatform(LatticeECP5Platform):
13+
name = "Logicbone"
14+
device = "LFE5UM5G-45F"
15+
package = "BG381"
16+
speed = "8"
17+
18+
default_clk = "refclk"
19+
20+
resources = [
21+
Resource("refclk", 0, Pins("M19", dir="i"),
22+
Clock(25e6), Attrs(IO_TYPE="LVCMOS18")),
23+
24+
# SerDes connections.
25+
Resource("serdes", 0,
26+
Subsignal("rx", DiffPairs("Y5", "Y6")),
27+
Subsignal("tx", DiffPairs("W4", "W5")),
28+
),
29+
Resource("serdes", 1,
30+
Subsignal("rx", DiffPairs("Y8", "Y7")),
31+
Subsignal("tx", DiffPairs("W8", "W9")),
32+
),
33+
34+
# VBUS Detection is on the USB-C PD controller for both ports.
35+
DirectUSBResource("usb", 0,
36+
d_p="B12", d_n="C12", pullup="C16",
37+
attrs=Attrs(IO_TYPE="LVCMOS33")
38+
),
39+
DirectUSBResource("usb", 1,
40+
d_p="R1", d_n="T1", pullup="T2",
41+
attrs=Attrs(IO_TYPE="LVCMOS33")
42+
),
43+
44+
*LEDResources(pins="D16 C15 C13 B13", attrs=Attrs(IO_TYPE="LVCMOS33"), invert=True),
45+
46+
*ButtonResources(pins="U2", attrs=Attrs(IO_TYPE="LVCMOS33"), invert=True),
47+
48+
*SPIFlashResources(0,
49+
cs_n="R2", clk="U3", cipo="V2", copi="W2", wp_n="Y2", hold_n="W1",
50+
attrs=Attrs(IO_TYPE="LVCMOS33")
51+
),
52+
53+
*SDCardResources(0,
54+
clk="E11", cmd="D15", cd="D14",
55+
dat0="D13", dat1="E13", dat2="E15", dat3="E13",
56+
attrs=Attrs(IO_TYPE="LVCMOS33")
57+
),
58+
59+
Resource("eth_clk125", 0, Pins("A19", dir="i"),
60+
Clock(125e6), Attrs(IO_TYPE="LVCMOS33")),
61+
Resource("eth_rgmii", 0,
62+
# Stolen for sys_reset usage on prototypes.
63+
# Subsignal("rst", PinsN("U17", dir="o")),
64+
Subsignal("int", Pins("B20", dir="i")),
65+
Subsignal("mdc", Pins("D12", dir="o")),
66+
Subsignal("mdio", Pins("B19", dir="io")),
67+
Subsignal("tx_clk", Pins("A15", dir="o")),
68+
Subsignal("tx_ctl", Pins("B15", dir="o")),
69+
Subsignal("tx_data", Pins("A12 A13 C14 A14", dir="o")),
70+
Subsignal("rx_clk", Pins("B18", dir="i")),
71+
Subsignal("rx_ctl", Pins("A18", dir="i")),
72+
Subsignal("rx_data", Pins("B17 A17 B16 A16", dir="i")),
73+
Attrs(IO_TYPE="LVCMOS33")
74+
),
75+
76+
Resource("ddr3", 0,
77+
Subsignal("rst", PinsN("P1", dir="o")),
78+
Subsignal("clk", DiffPairs("M4", "N5", dir="o"), Attrs(IO_TYPE="LVDS")),
79+
Subsignal("clk_en", Pins("K4", dir="o")),
80+
Subsignal("cs", PinsN("M3", dir="o")),
81+
Subsignal("we", PinsN("E4", dir="o")),
82+
Subsignal("ras", PinsN("L1", dir="o")),
83+
Subsignal("cas", PinsN("M1", dir="o")),
84+
Subsignal("a", Pins("D5 F4 B3 F3 E5 C3 C4 A5 A3 B5 G3 F5 D2 A4 D3 E3", dir="o")),
85+
Subsignal("ba", Pins("B4 H5 N2", dir="o")),
86+
Subsignal("dqs", DiffPairs("K2 H4", "J1 G5", dir="io"), Attrs(IO_TYPE="LVDS")),
87+
Subsignal("dq", Pins("G2 K1 F1 K3 H2 J3 G1 H1 B1 E1 A2 F2 C1 E2 C2 D1", dir="io")),
88+
Subsignal("dm", Pins("L4 J5", dir="o")),
89+
Subsignal("odt", Pins("C5", dir="o")),
90+
Attrs(IO_TYPE="SSTL135_I")
91+
)
92+
]
93+
connectors = [
94+
Connector("P8", 0, """
95+
- - C20 D19 D20 E19 E20 F19 F20 G20 - - - - - -
96+
- - - - - - G19 H20 J20 K20 C18 D17 D18 E17 E18 F18
97+
F17 G18 E16 F16 G16 H16 J17 J16 H18 H17 J19 K19 J18 K18
98+
"""),
99+
Connector("P9", 0, """
100+
- - - - - - - - - - - A11 B11 A10 C10 A9
101+
B9 C11 A8 - - D9 C8 B8 A7 A6 B6 D8 C7 D7 C6 D6
102+
- - - - - - - - - B10 E10 - - -
103+
"""),
104+
]
105+
106+
def toolchain_prepare(self, fragment, name, **kwargs):
107+
overrides = dict(ecppack_opts="--compress --spimode qspi --freq 38.8")
108+
overrides.update(kwargs)
109+
return super().toolchain_prepare(fragment, name, **overrides)
110+
111+
def toolchain_program(self, products, name):
112+
dfu_util = os.environ.get("DFU_UTIL", "dfu-util")
113+
with products.extract("{}.bit".format(name)) as bitstream_filename:
114+
subprocess.check_call([
115+
dfu_util, "-d", "1d50:615d", "-a", "0", "-R",
116+
"-D", bitstream_filename
117+
])
118+
119+
120+
class Logicbone85FPlatform(LogicbonePlatform):
121+
name = "Logicbone (85F Variant)"
122+
device = "LFE5UM5G-85F"
123+
124+
125+
if __name__ == "__main__":
126+
import argparse
127+
from .test.blinky import Blinky
128+
129+
parser = argparse.ArgumentParser()
130+
parser.add_argument("--variant", choices=("85", "45"), default="45",
131+
help="platform variant (default: %(default)s)")
132+
133+
args = parser.parse_args()
134+
if args.variant == "45":
135+
platform = LogicbonePlatform()
136+
if args.variant == "85":
137+
platform = Logicbone85FPlatform()
138+
platform.build(Blinky(), do_program=True)

0 commit comments

Comments
 (0)