1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
import subprocess
import textwrap
from amaranth.build import *
from amaranth.vendor.xilinx_spartan_3_6 import *
from .resources import *
__all__ = ["AtlysPlatform"]
class AtlysPlatform(XilinxSpartan6Platform):
"""Platform file for Digilent Atlys Spartan 6 board.
https://reference.digilentinc.com/reference/programmable-logic/atlys/start"""
device = "xc6slx45"
package = "csg324"
speed = "3"
def __init__(self, *, JP12="2V5", **kwargs):
super().__init__(**kwargs)
assert JP12 in ["2V5", "3V3"]
self._JP12 = JP12
def bank2_iostandard(self):
return "LVCMOS25" if self._JP12 == "2V5" else "LVCMOS33"
default_clk = "clk100"
default_rst = "rst"
resources = [
Resource("rst", 0, PinsN("T15", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # RESET
Resource("clk100", 0, Pins("L15", dir="i"),
Clock(100e6), Attrs(IOSTANDARD="LVCMOS33")), # GCLK
Resource("led", 0, Pins("U18", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD0
Resource("led", 1, Pins("M14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD1
Resource("led", 2, Pins("N14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD2
Resource("led", 3, Pins("L14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD3
Resource("led", 4, Pins("M13", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD4
Resource("led", 5, Pins("D4", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD5
Resource("led", 6, Pins("P16", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD6
Resource("led", 7, Pins("N12", dir="o"), Attrs(IOSTANDARD=bank2_iostandard)), # LD7
Resource("button", 0, Pins("N4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNU
Resource("button", 1, Pins("P4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNL
Resource("button", 2, Pins("P3", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTND
Resource("button", 3, Pins("F6", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNR
Resource("button", 4, Pins("F5", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNC
Resource("switch", 0, Pins("A10", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW0
Resource("switch", 1, Pins("D14", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW1
Resource("switch", 2, Pins("C14", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW2
Resource("switch", 3, Pins("P15", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW3
Resource("switch", 4, Pins("P12", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW4
Resource("switch", 5, Pins("R5", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW5
Resource("switch", 6, Pins("T5", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW6
Resource("switch", 7, Pins("E4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # SW7
UARTResource(0, rx="A16", tx="B16", attrs=Attrs(IOSTANDARD="LVCMOS33")), # J17/UART
PS2Resource(0, # PS/2 keyboard interface converted from J13 "HOST" USB connector
clk="P17", dat="N15", attrs=Attrs(IOSTANDARD="LVCMOS33")),
PS2Resource(1, # PS/2 mouse interface converted from J13 "HOST" USB connector
clk="N18", dat="P18", attrs=Attrs(IOSTANDARD="LVCMOS33")),
*SPIFlashResources(0,
cs_n="AE14", clk="AH18", copi="AF14", cipo="AF20", wp_n="AG21", hold_n="AG17",
attrs=Attrs(IOSTANDARD="LVCMOS25", SLEW="FAST"),
),
Resource("ddr2", 0,
Subsignal("clk", DiffPairs("G3", "G1", dir="o"),
Attrs(IOSTANDARD="DIFF_SSTL18_II", IN_TERM="NONE")),
Subsignal("clk_en", Pins("H7", dir="o")),
Subsignal("we", PinsN("E3", dir="o")),
Subsignal("ras", PinsN("L5", dir="o")),
Subsignal("cas", PinsN("K5", dir="o")),
Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6", dir="o")),
Subsignal("ba", Pins("F2 F1 E1", dir="o")),
Subsignal("dqs", DiffPairs("P2 L4", "P1 L3", dir="o"),
Attrs(IOSTANDARD="DIFF_SSTL18_II")),
Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1", dir="io")),
Subsignal("dm", Pins("K4 K3", dir="o")),
Subsignal("odt", Pins("K6", dir="o")),
Attrs(IOSTANDARD="SSTL18_II", SLEW="FAST"),
),
Resource("eth_gmii", 0,
Subsignal("rst", PinsN("G13", dir="o")),
Subsignal("int", PinsN("L16", dir="o")),
Subsignal("mdio", Pins("N17", dir="io")),
Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz
Subsignal("gtx_clk", Pins("L12", dir="o")),
Subsignal("tx_clk", Pins("K16", dir="i")),
Subsignal("tx_en", Pins("H15", dir="o")),
Subsignal("tx_er", Pins("G18", dir="o")),
Subsignal("tx_data", Pins("H16 H13 K14 K13 J13 G14 H12 K12", dir="o")),
Subsignal("rx_clk", Pins("K15", dir="i")),
Subsignal("rx_dv", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")),
Subsignal("rx_er", Pins("F18", dir="i")),
Subsignal("rx_data", Pins("G16 H14 E16 F15 F14 E18 D16 D17", dir="i")),
Subsignal("col", Pins("C17", dir="i")),
Subsignal("crs", Pins("C18", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
Resource("eth_rgmii", 0,
Subsignal("rst", PinsN("G13", dir="o")),
Subsignal("int", PinsN("L16", dir="o")),
Subsignal("mdio", Pins("N17", dir="io")),
Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz
Subsignal("tx_clk", Pins("L12", dir="o")),
Subsignal("tx_ctl", Pins("H15", dir="o")),
Subsignal("tx_data", Pins("H16 H13 K14 K13", dir="o")),
Subsignal("rx_clk", Pins("K15", dir="i")),
Subsignal("rx_ctl", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")),
Subsignal("rx_data", Pins("G16 H14 E16 F15", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
Resource("eth_mii", 0,
Subsignal("rst", PinsN("G13", dir="o")),
Subsignal("int", PinsN("L16", dir="o")),
Subsignal("mdio", Pins("N17", dir="io")),
Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz
Subsignal("tx_clk", Pins("K16", dir="i")),
Subsignal("tx_en", Pins("H15", dir="o")),
Subsignal("tx_er", Pins("G18", dir="o")),
Subsignal("tx_data", Pins("H16 H13 K14 K13", dir="o")),
Subsignal("rx_clk", Pins("K15", dir="i")),
Subsignal("rx_dv", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")),
Subsignal("rx_er", Pins("F18", dir="i")),
Subsignal("rx_data", Pins("G16 H14 E16 F15", dir="i")),
Subsignal("col", Pins("C17", dir="i")),
Subsignal("crs", Pins("C18", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
# Device does not support RMII
Resource("eth_tbi", 0,
Subsignal("rst", PinsN("G13", dir="o")),
Subsignal("int", PinsN("L16", dir="o")),
Subsignal("mdio", Pins("N17", dir="io")),
Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz
Subsignal("tx_clk", Pins("L12", dir="o")),
Subsignal("tx_data", Pins("H16 H13 K14 K13 J13 G14 H12 K12 H15 G18", dir="o")),
Subsignal("rx_clk", Pins("K15 L12", dir="i")),
Subsignal("rx_data", Pins("G16 H14 E16 F15 F14 E18 D16 D17 F17 F18", dir="i")),
Subsignal("lpbk", Pins("C17", dir="o"), Attrs(PULLDOWN="TRUE")),
Subsignal("comma", Pins("C18", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
Resource("eth_rtbi", 0,
Subsignal("rst", PinsN("G13", dir="o")),
Subsignal("int", PinsN("L16", dir="o")),
Subsignal("mdio", Pins("N17", dir="io")),
Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz
Subsignal("tx_clk", Pins("L12", dir="o")),
Subsignal("tx_data", Pins("H16 H13 K14 K13 H15", dir="o")),
Subsignal("rx_clk", Pins("K15", dir="i")),
Subsignal("rx_data", Pins("G16 H14 E16 F15 F17", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
Resource("hdmi", 0, # J1, input only due to on board buffer, HDMI A connector
Subsignal("scl", Pins("C13"), Attrs(IOSTANDARD="I2C")),
Subsignal("sda", Pins("A13"), Attrs(IOSTANDARD="I2C")),
Subsignal("clk", DiffPairs("D11", "C11", dir="i")),
Subsignal("d", DiffPairs("G9 B11 B12", "F9 A11 A12", dir="i")),
Attrs(IOSTANDARD="TMDS_33"),
),
Resource("hdmi", 1, # J2, output only due to on board buffer, HDMI A connector
Subsignal("scl", Pins("D9"), Attrs(IOSTANDARD="I2C")),
Subsignal("sda", Pins("C9"), Attrs(IOSTANDARD="I2C")),
Subsignal("clk", DiffPairs("B6", "A6", dir="o")),
Subsignal("d", DiffPairs("D8 C7 B8", "C8 A7 A8", dir="o")),
Attrs(IOSTANDARD="TMDS_33"),
),
Resource("hdmi", 2, # J3, input only due to on board buffer, HDMI A connector
Subsignal("scl", Pins("M16"), Attrs(IOSTANDARD="I2C")),
Subsignal("sda", Pins("M18"), Attrs(IOSTANDARD="I2C")),
Subsignal("clk", DiffPairs("H17", "H18", dir="i")),
Subsignal("d", DiffPairs("K17 L17 J16", "K18 L18 J18", dir="i")),
Attrs(IOSTANDARD="TMDS_33"),
),
Resource("hdmi", 3, # JA, input/output as it is unbuffered, HDMI D connector
Subsignal("scl", Pins("C13"), Attrs(IOSTANDARD="I2C")),
Subsignal("sda", Pins("A13"), Attrs(IOSTANDARD="I2C")),
Subsignal("clk", DiffPairs("T9", "V9")),
Subsignal("d", DiffPairs("R3 T4 N5", "T3 V4 P6")),
Attrs(IOSTANDARD="TMDS_33"),
),
Resource("ac97", 0,
Subsignal("clk", Pins("L13", dir="o")),
Subsignal("sync", Pins("U17", dir="o")),
Subsignal("reset", Pins("T17", dir="o")),
Subsignal("sdo", Pins("N18", dir="o")),
Subsignal("sdi", Pins("T18", dir="i")),
Attrs(IOSTANDARD="LVCMOS33")
),
]
connectors = [
Connector("pmod", 0, "T3 R3 P6 N5 - - V9 T9 V4 T4 - -"), # JB
Connector("vhdci", 0, # JC
"U16 - U15 U13 - M11 R11 - T12 N10 - M10 U11 - R10 - - - - U10 - R8 M8 - U8 U7 - N7 T6 - R7 N6 - U5 "
"V16 - V15 V13 - N11 T11 - V12 P11 - N9 V11 - T10 - - - - V10 - T8 N8 - V8 V7 - P8 V6 - T7 P7 - V5 "
),
]
def toolchain_program(self, products, name):
with products.extract("{}.bit".format(name)) as bitfile:
cmd = textwrap.dedent("""
setMode -bscan
setCable -port auto
addDevice -p 1 -file "{}"
program -p 1
exit
""").format(bitfile).encode('utf-8')
subprocess.run(["impact", "-batch"], input=cmd, check=True)
if __name__ == "__main__":
from .test.blinky import *
AtlysPlatform().build(Blinky(), do_program=True)
|