2 # see https://bugs.libre-soc.org/show_bug.cgi?id=739
4 from spec
.base
import PinSpec
5 from parse
import Parse
8 from pprint
import pprint
9 from spec
.ifaceprint
import display
, display_fns
, check_functions
10 from spec
.ifaceprint
import display_fixed
11 from collections
import OrderedDict
14 # TODO - Turn the number of pins per side into a variable?
15 pinbanks
= OrderedDict((
44 'RG0': 'Gigabit Ethernet 0',
45 'RG1': 'Gigabit Ethernet 1',
46 'RG2': 'Gigabit Ethernet 2',
47 'RG3': 'Gigabit Ethernet 3',
48 'RG4': 'Gigabit Ethernet 4',
49 'ULPI0': 'USB ULPI0 PHY',
50 'ULPI1': 'USB ULPI1 PHY',
52 'UART0': 'UART (TX/RX)',
54 'VDD': '1.8V Core Power',
55 'VSS': '1.8V Core GND',
56 'VDD': '3.3V I/O Power',
57 'VSS': '3.3V I/O GND',
58 'SYS': 'System Control',
59 'MSPI0': 'SPI Master 0 (general)',
62 'EINT': 'External Interrupt',
64 'QSPI': 'QSPI Master',
68 ps
= PinSpec(pinbanks
, fixedpins
, function_names
)
70 ps
.sdram1("", ('W', 0), 0, 15, 6, rev
=True) # AD4-9, turned round
71 ps
.vdd("E", ('W', 6), 0, 0, 1)
72 ps
.vss("E", ('W', 7), 0, 0, 1)
73 ps
.vdd("I", ('W', 8), 0, 0, 1)
74 ps
.vss("I", ('W', 9), 0, 0, 1)
75 ps
.sdram1("", ('W', 10), 0, 0, 15, rev
=True) # SDRAM DAM0, D0-7, AD0-3
76 ps
.mi2c("", ('W', 26), 0, 0, 2)
77 ps
.vss("I", ('W', 28), 0, 1, 1)
78 ps
.vdd("I", ('W', 29), 0, 1, 1)
79 ps
.vss("E", ('W', 30), 0, 1, 1)
80 ps
.vdd("E", ('W', 31), 0, 1, 1)
82 ps
.sdram2("", ('S', 0), 0, 0, 4) # 1st 4, AD10-12,DQM1
83 ps
.vdd("E", ('S', 4), 0, 2, 1)
84 ps
.vss("E", ('S', 5), 0, 2, 1)
85 ps
.vdd("I", ('S', 6), 0, 2, 1)
86 ps
.vss("I", ('S', 7), 0, 2, 1)
87 ps
.sdram2("", ('S', 8), 0, 4, 8) # D8-15
88 ps
.sdram1("", ('S', 16), 0, 21, 9) # clk etc.
89 ps
.vss("I", ('S', 22), 0, 3, 1)
90 ps
.vdd("I", ('S', 23), 0, 3, 1)
91 ps
.vss("E", ('S', 24), 0, 3, 1)
92 ps
.vdd("E", ('S', 25), 0, 3, 1)
93 ps
.uart("0", ('S', 26), 0)
94 ps
.mspi("0", ('S', 28), 0)
96 ps
.gpio("", ('E', 0), 0, 0, 6) # GPIO 0-5
97 ps
.vss("E", ('E', 6), 0, 4, 1)
98 ps
.vdd("E", ('E', 7), 0, 4, 1)
99 ps
.vdd("I", ('E', 8), 0, 4, 1)
100 ps
.vss("I", ('E', 9), 0, 4, 1)
101 ps
.gpio("", ('E', 10), 0, 6, 3) # GPIO 6-8
102 ps
.jtag("", ('E', 13), 0, 0, 4)
103 ps
.gpio("", ('E', 17), 0, 9, 5) # GPIO 9-13
104 #ps.vss("I", ('E', 22), 0, 5, 1)
105 #ps.vdd("I", ('E', 23), 0, 5, 1)
106 #ps.vss("E", ('E', 24), 0, 5, 1)
107 #ps.vdd("E", ('E', 25), 0, 5, 1)
108 #ps.gpio("", ('E', 26), 0, 14, 2) # GPIO 14-15
109 #ps.eint("", ('E', 28), 0, 0, 3)
110 ps
.sys("", ('E', 63), 0, 5, 1) # analog VCO out in right top
112 ps
.vss("E", ('N', 6), 0, 6, 1)
113 ps
.vdd("E", ('N', 7), 0, 6, 1)
114 ps
.vdd("I", ('N', 8), 0, 6, 1)
115 ps
.vss("I", ('N', 9), 0, 6, 1)
117 #ps.pwm("", ('N', 2), 0, 0, 2) comment out (litex problem 25mar2021)
118 #ps.mspi("1", ('N', 7), 0) comment out (litex problem 25mar2021)
119 #ps.sdmmc("0", ('N', 11), 0) # comment out (litex problem 25mar2021)
120 ps
.sys("", ('N', 59), 0, 0, 5) # all but analog out in top right
121 ps
.vss("I", ('N', 54), 0, 7, 1)
122 ps
.vdd("I", ('N', 55), 0, 7, 1)
123 ps
.vss("E", ('N', 56), 0, 7, 1)
124 ps
.vdd("E", ('N', 57), 0, 7, 1)
126 ps
.rgmii("0", ('E', 42), 0, 0, 18)
127 ps
.rgmii("1", ('E', 22), 0, 0, 18)
128 ps
.rgmii("2", ('N', 31), 0, 0, 18)
129 #ps.mquadspi("1", ('S', 0), 0)
131 print ("ps clocks", ps
.clocks
)
133 # Scenarios below can be spec'd out as either "find first interface"
134 # by name/number e.g. SPI1, or as "find in bank/mux" which must be
135 # spec'd as "BM:Name" where B is bank (A-F), M is Mux (0-3)
136 # EINT and PWM are grouped together, specially, but may still be spec'd
137 # using "BM:Name". Pins are removed in-order as listed from
138 # lists (interfaces, EINTs, PWMs) from available pins.
141 # 'SD0', litex problem 25mar2021
142 'UART0', 'GPIOS', 'GPIOE', 'JTAG', 'PWM', 'EINT',
145 'RG0', 'RG1', 'RG2', 'RG3', 'RG4',
146 # 'MSPI1', litex problem 25mar2021
149 ngi_router_pwm
= []#['B0:PWM_0']
151 'SD0': 'user-facing: internal (on Card), multiplexed with JTAG\n'
152 'and UART2, for debug purposes',
161 'B1:LCD/22': '18-bit RGB/TTL LCD',
162 'ULPI0/8': 'user-facing: internal (on Card), USB-OTG ULPI PHY',
163 'ULPI1': 'dual USB2 Host ULPI PHY'
166 ps
.add_scenario("NGI ROUTER Libre-SOC 180nm", ngi_router
, ngi_router_eint
, ngi_router_pwm
,
172 # map pins to litex name conventions, primarily for use in coriolis2
173 # yes this is a mess. it'll do the job though. improvements later
174 def pinparse(psp
, pinspec
):
175 p
= Parse(pinspec
, verify
=False)
179 print (p
.muxed_cells
)
180 print (p
.muxed_cells_bank
)
182 # TODO - Turn the number of pins per side into a variable?
187 pads
= {'N': pn
, 'S': ps
, 'E': pe
, 'W': pw
}
195 for (padnum
, name
, x
), bank
in zip(p
.muxed_cells
, p
.muxed_cells_bank
):
198 domain
= None # TODO, get this from the PinSpec. sigh
200 start
= p
.bankstart
[bank
]
201 banknum
= padnum
- start
202 print ("bank", bank
, banknum
, "padname", name
, padnum
, x
)
206 if name
.startswith('vss'):
207 name
= 'p_%s_' % name
[:-2] + name
[-1]
209 name
= 'ground_' + name
[-1]
212 name
= 'ioground_' + name
[-1]
216 elif name
.startswith('vdd'):
219 name
= 'power_' + name
[-1]
223 name
= 'iopower_' + name
[-1]
227 elif name
.startswith('sys'):
229 if name
== 'sys_pllclk':
230 pad
= ["p_"+name
, name
, name
]
231 elif name
== 'sys_rst':
232 #name = 'p_sys_rst_1'
233 pad
= [name
, name
, name
]
234 padbank
[banknum
] = name
235 print ("sys_rst add", bank
, banknum
, name
)
237 elif name
== 'sys_pllclk':
239 elif name
== 'sys_pllvcout':
240 name
= 'sys_pll_vco_o'
241 pad
= ['p_' + name
, name
, name
, "A"] # A for Analog
242 elif name
== 'sys_plltestout':
243 name
= 'sys_pll_testout_o'
244 pad
= ['p_' + name
, name
, name
]
245 elif name
.startswith('sys_pllsel'):
247 name2
= 'sys_clksel_i(%s)' % i
248 name
= 'p_sys_clksel_' + i
249 pad
= [name
, name2
, name2
]
251 # iopads.append([pname, name, name])
252 print ("sys pad", name
)
254 elif name
.startswith('mspi0') or name
.startswith('mspi1'):
259 elif suffix
== 'nss':
261 if name
.startswith('mspi0'):
262 prefix
= 'spimaster_'
264 prefix
= 'spisdcard_'
265 litex_name
= name
[:6] + suffix
266 name
= prefix
+ suffix
267 pad
= ['p_' + name
, name
, name
]
269 elif name
.startswith('sd0'):
271 if name
.startswith('sd0_d'):
273 name
= 'sdcard_data' + i
274 name2
= 'sdcard_data_%%s(%s)' % i
275 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
276 elif name
.startswith('sd0_cmd'):
278 name2
= 'sdcard_cmd_%s'
279 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
281 name
= 'sdcard_' + name
[4:]
282 pad
= ['p_' + name
, name
, name
]
283 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
285 elif name
.startswith('sdr'):
287 if name
== 'sdr_clk':
289 pad
= ['p_' + name
, name
, name
]
290 elif name
.startswith('sdr_ad'):
292 name
= 'sdram_a_' + i
293 name2
= 'sdram_a(%s)' % i
294 pad
= ['p_' + name
, name2
, name2
]
295 elif name
.startswith('sdr_ba'):
297 name
= 'sdram_ba_' + i
298 name2
= 'sdram_ba(%s)' % i
299 pad
= ['p_' + name
, name2
, name2
]
300 elif name
.startswith('sdr_dqm'):
302 name
= 'sdram_dm_' + i
303 name2
= 'sdram_dm(%s)' % i
304 pad
= ['p_' + name
, name2
, name2
]
305 elif name
.startswith('sdr_d'):
307 name
= 'sdram_dq_' + i
308 name2
= 'sdram_dq_%%s(%s)' % i
309 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
310 elif name
== 'sdr_csn0':
312 pad
= ['p_' + name
, name
, name
]
313 elif name
[-1] == 'n':
314 name
= 'sdram_' + name
[4:-1] + '_n'
315 pad
= ['p_' + name
, name
, name
]
317 name
= 'sdram_' + name
[4:]
318 pad
= ['p_' + name
, name
, name
]
319 litex_name
= orig_name
[:4] + "_".join(name
.split("_")[1:])
321 elif name
.startswith('uart'):
323 name
= 'uart_' + name
[6:]
324 pad
= ['p_' + name
, name
, name
]
326 elif name
.startswith('gpio'):
331 name2
= 'gpio_%%s(%s)' % i
332 pad
= ['p_' + name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
333 print ("GPIO pad", name
, pad
)
334 litex_name
= "gpio_%s" % gbank
+ "_".join(name
.split("_")[1:])
336 elif name
.startswith('mtwi'):
339 litex_name
= 'mtwi' + suffix
340 name
= 'i2c' + suffix
341 if name
.startswith('i2c_sda'):
343 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
344 print ("I2C pad", name
, pad
)
346 pad
= ['p_' + name
, name
, name
]
348 elif name
.startswith('twi'):
350 name
= 'i2c' + name
[3:]
352 pad
= ['p_'+name
, name
, name2
% 'o', name2
% 'i', name2
% 'oe']
353 print ("I2C pad", name
, pad
)
355 elif name
.startswith('eint'):
359 name2
= 'eint_%s' % i
360 pad
= ['p_' + name
, name2
, name2
]
362 elif name
.startswith('pwm'):
366 name2
= 'pwm(%s)' % i
367 pad
= ['p_' + name
, name2
, name2
]
369 pad
= ['p_' + name
, name
, name
]
370 print ("GPIO pad", name
, pad
)
372 if litex_name
is None:
376 if name
and name
.startswith('jtag'):
379 if name
and not name
.startswith('p_'):
380 if 'power' not in name
and 'ground' not in name
:
383 padbank
[banknum
] = name
385 if domain
is not None:
386 if domain
not in domains
:
388 domains
[domain
].append(name
)
390 if domain
in psp
.clocks
and orig_name
.startswith(dl
):
391 clk
= psp
.clocks
[domain
]
392 if clk
.lower() in orig_name
: # TODO, might over-match
393 clocks
[domain
] = name
395 pinmap
[orig_name
] = name
396 litexmap
[litex_name
] = name
399 if domain
and pad
is not None:
400 # append direction from spec/domain. damn awkward processing
402 fn
, name
= orig_name
.split("_")
407 for k
in psp
.byspec
.keys():
408 if k
.startswith(domain
):
410 print ("spec found", domain
, spec
)
411 assert spec
is not None
414 if pname
.lower().startswith(name
):
416 print ("found spec", found
)
417 assert found
is not None
418 # whewwww. add the direction onto the pad spec list
425 elif pad
is not None:
430 for pl
in [pe
, pw
, pn
, ps
]:
431 for i
in range(len(pl
)):
433 name
= 'nc_%d' % nc_idx
434 name2
= 'nc(%d)' % nc_idx
437 iopads
.append([name
, name2
, name2
, "-"])
453 print ("chip domains (excluding sys-default)")
455 print ("chip clocks (excluding sys-default)")
465 'pads.instances' : iopads
,
466 'pins.specs' : psp
.byspec
,
468 'litex.map' : litexmap
,
469 'chip.domains' : domains
,
470 'chip.clocks' : clocks
,
471 'chip.n_intpower': n_intpower
,
472 'chip.n_extpower': n_extpower
,