Skip to content

Commit c26a72e

Browse files
timkpainewhitequark
authored andcommitted
Add nitefuryii/litefury
1 parent ba3b403 commit c26a72e

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

amaranth_boards/nitefury.py

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import os
2+
import subprocess
3+
import textwrap
4+
import unittest
5+
6+
from amaranth.build import *
7+
from amaranth.vendor import XilinxPlatform
8+
from .resources import *
9+
10+
11+
__all__ = ["NitefuryIIPlatform", "LitefuryPlatform"]
12+
13+
14+
class _BasePlatform(XilinxPlatform):
15+
speed = "2"
16+
default_clk = "clk200"
17+
18+
resources = [
19+
Resource("clk200", 0, DiffPairs(p="J19", n="H19", dir="i"),
20+
Clock(200e6), Attrs(IOSTANDARD="DIFF_SSTL15")),
21+
# 4 Programmable LEDs
22+
*LEDResources(pins="G3 H3 G4 H4", attrs=Attrs(IOSTANDARD="LVCMOS33")),
23+
# SPIFlash
24+
*SPIFlashResources(0,
25+
cs_n="T19", clk="L16", copi="P22", cipo="R22", wp_n="P21", hold_n="R21",
26+
attrs=Attrs(IOSTANDARD="LVCMOS33")
27+
),
28+
# 1 M.2 indicator LED
29+
Resource("m2led", 0, Pins("M1"), Attrs(IOSTANDARD="LVCMOS33")),
30+
# PCIE
31+
Resource("pcie", 0,
32+
Subsignal("clkreq", PinsN("G1", dir="o"), Attrs(IOSTANDARD="LVCMOS33")),
33+
Subsignal("rst", PinsN("J1", dir="o"), Attrs(IOSTANDARD="LVCMOS33", PULLUP=1)),
34+
Subsignal("clk", DiffPairs(p="F6", n="E6", dir="i"), Attrs(IOSTANDARD="DIFF_SSTL15")),
35+
Subsignal("rx", DiffPairs(p="B10 B8 D11 D9", n="A10 A8 C11 C9", dir="i")),
36+
Subsignal("tx", DiffPairs(p="B6 B4 D5 D7", n="A6 A4 C5 C7", dir="o")),
37+
),
38+
# DDR
39+
Resource("ddr3", 0,
40+
Subsignal("rst", PinsN("K16", dir="o"), Attrs(IOStandard="LVCMOS15")),
41+
Subsignal("clk", DiffPairs(p="K17", n="J17", dir="o")),
42+
Subsignal("clk_en", Pins("H22", dir="o")),
43+
# Subsignal("cs", PinsN("U8", dir="o")),
44+
Subsignal("we", PinsN("L16", dir="o")),
45+
Subsignal("ras", PinsN("H20", dir="o")),
46+
Subsignal("cas", PinsN("K18", dir="o")),
47+
Subsignal("a", Pins("M15 L21 M16 L18 K21 M18 M21 N20 M20 N19 J21 M22 K22 N18 N22 J22", dir="o")),
48+
Subsignal("ba", Pins("L19 J20 L20", dir="o")),
49+
Subsignal("dqs", DiffPairs(p="F18 B21", n="E18 A21", dir="io"),
50+
Attrs(IOSTANDARD="DIFF_SSTL135")),
51+
Subsignal("dq", Pins("D19 B20 E19 A20 F19 C19 F20 C18 E22 G21 D20 E21 C22 D21 B22 D22", dir="io"),
52+
Attrs(IN_TERM="UNTUNED_SPLIT_50")),
53+
Subsignal("dm", Pins("A19 G22", dir="o")),
54+
Subsignal("odt", Pins("K19", dir="o")),
55+
Attrs(IOSTANDARD="SSTL15", SLEW="FAST"),
56+
),
57+
]
58+
connectors = []
59+
60+
def toolchain_prepare(self, fragment, name, **kwargs):
61+
overrides = {
62+
"script_before_bitstream":
63+
"""
64+
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
65+
set_property BITSTREAM.CONFIG.CONFIGRATE 16 [current_design]
66+
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
67+
""",
68+
"script_after_bitstream":
69+
"write_cfgmem -force -format bin -interface spix4 -size 16 "
70+
"-loadbit \"up 0x0 {name}.bit\" -file {name}.bin".format(name=name),
71+
"add_constraints":
72+
"""
73+
set_property INTERNAL_VREF 0.675 [get_iobanks 34]
74+
set_property CFGBVS VCCO [current_design]
75+
set_property CONFIG_VOLTAGE 3.3 [current_design]
76+
"""
77+
}
78+
return super().toolchain_prepare(fragment, name, **overrides, **kwargs)
79+
80+
def toolchain_program(self, product, name, *, programmer="openfpgaloader", flash=True):
81+
assert programmer in ("vivado", "openfpgaloader")
82+
83+
if programmer == "vivado":
84+
if flash:
85+
# It does not appear possible to reset the FPGA via TCL after
86+
# flash programming.
87+
with product.extract("{}.bin".format(name)) as bitstream_filename:
88+
cmd = textwrap.dedent("""
89+
open_hw_manager
90+
connect_hw_server
91+
open_hw_target
92+
current_hw_device [lindex [get_hw_devices xc7a*] 0]]
93+
create_hw_cfgmem -hw_device [current_hw_device] s25fl256sxxxxxx0-spi-x1_x2_x4
94+
set_property PROGRAM.FILES {{{}}} [current_hw_cfgmem]
95+
set_property PROGRAM.ADDRESS_RANGE {{use_file}} [current_hw_cfgmem]
96+
set_property PROGRAM.BLANK_CHECK 1 [current_hw_cfgmem]
97+
set_property PROGRAM.ERASE 1 [current_hw_cfgmem]
98+
set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]
99+
set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]
100+
create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]
101+
program_hw_devices
102+
program_hw_cfgmem
103+
close_hw_manager
104+
puts "Vivado TCL cannot reset boards. Reset or power-cycle your board now."
105+
""").format(bitstream_filename).encode("utf-8")
106+
subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True)
107+
else:
108+
with product.extract("{}.bit".format(name)) as bitstream_filename:
109+
cmd = textwrap.dedent("""
110+
open_hw_manager
111+
connect_hw_server
112+
open_hw_target
113+
current_hw_device [lindex [get_hw_devices] 0]
114+
set_property PROGRAM.FILE {{{}}} [current_hw_device]
115+
program_hw_devices
116+
close_hw_manager
117+
""").format(bitstream_filename).encode("utf-8")
118+
subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True)
119+
else:
120+
# openfpgaloader
121+
openfpgaloader = os.environ.get("OPENFPGALOADER", "openFPGALoader")
122+
with product.extract("{}.bin".format(name)) as fn:
123+
# TODO: @timkpaine has digilent_hs3 cable
124+
subprocess.check_call([openfpgaloader, "-c", "digilent_hs3", fn])
125+
126+
127+
class LitefuryPlatform(_BasePlatform):
128+
device = "xc7a100t"
129+
package = "fgg484"
130+
131+
132+
class NitefuryIIPlatform(_BasePlatform):
133+
device = "xc7a200t"
134+
package = "fbg484"
135+
136+
137+
class TestCase(unittest.TestCase):
138+
def test_smoke(self):
139+
from .test.blinky import Blinky
140+
NitefuryIIPlatform().build(Blinky(), do_build=False)
141+
142+
143+
if __name__ == "__main__":
144+
from .test.blinky import *
145+
NitefuryIIPlatform().build(Blinky(), do_program=True)

0 commit comments

Comments
 (0)