-
Notifications
You must be signed in to change notification settings - Fork 6
/
netlist_to_xdc.py
119 lines (105 loc) · 3.96 KB
/
netlist_to_xdc.py
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
import sys
# Somewhat specialized tool for creating an xdc file for the Marble board,
# based on a netlist file exported from KiCad.
# In the KiCad (version 5.1.x) schematic GUI (eeschema), use menu picks
# Tools / Generate Netlist File
# OrcadPCB2 tab / Generate Netlist / Save
# result shows up as AMC_FMC_Carrier-PcbDoc.net
# Finally from the command line run
# "python3 netlist_to_xdc AMC_FMC_Carrier_PcbDoc.net"
# result shows up as Marble.xdc
io_type = {
'/SDRAM/': 'SSTL135',
'/ETH_PHY/': 'LVCMOS25',
'/FPGA/FPGA_MGT/': 'DIFF_SSTL15',
'/FPGA/FPGA_15_16/': 'LVCMOS33',
'/PMOD/': 'LVCMOS33',
'/AMC_connector/': 'LVCMOS25',
'/FPGA/FPGA_13_14/': 'LVCMOS25',
'/FMC_2/': 'DIFF_HSTL_II_25',
'/FMC_1/': 'DIFF_HSTL_II_25',
'/FPGA/': 'LVCMOS33',
'/FPGA/FPGA_PWR&MISC/': 'LVCMOS33',
'/': 'LVCMOS25'
}
def edit_row(row, text):
if text == 'FMC1':
text = '/FMC_1/'
if text == 'FMC2':
text = '/FMC_2/'
io_number, name = row.replace(text, '').split(" ")
# Compared to earlier versions, some signals are run through
# level translators. The schematic codes the FPGA side of the translator
# chip with "_T" suffix.
# Drop that here. No application signal names have that suffix.
if name[-2:] == "_T":
name = name[:-2]
# Special case of the above, I2C_{SCL,SDA} are the voltage-translated
# versions of I2C_FPGA_{SCL,SDA}.
if name[:5] == "I2C_S":
name = "I2C_FPGA_S" + name[5:]
x_prefix = 'set_property -dict {PACKAGE_PIN ' + io_number + ' '
x_suffix = '} [get_ports ' + name + ']'
if text == '/FPGA/':
if '_P' in row or '_N' in row:
return x_prefix + 'IOSTANDARD ' + 'DIFF_SSTL135' + x_suffix
if 'DDR3_' in row:
return x_prefix + 'IOSTANDARD ' + 'SSTL135' + x_suffix
if "/FPGA/" in text and "TMDS" in row:
return x_prefix + 'IOSTANDARD ' + 'TMDS_33' + x_suffix
return x_prefix + 'IOSTANDARD ' + io_type[text] + x_suffix
def main(filename):
# reading netlist file
with open(filename, 'r') as netlist:
data = netlist.readlines()
subs = 'XC7A100T-2FGG484C'
for i in data:
if subs in i:
res = i
fpga_index = data.index(res)
out_file = "Marble.xdc"
f = open(out_file, "w")
cnt = 0
for row in data[fpga_index+1:fpga_index+485]:
if '/' in row or 'FMC' in row:
row = row.replace('(', '')
row = row.replace(')', '')
row = row.strip()
if '/SDRAM/' in row:
row = edit_row(row, '/SDRAM/')
elif '/FPGA/FPGA_MGT/' in row:
row = edit_row(row, '/FPGA/FPGA_MGT/')
elif '/FPGA/FPGA_15_16/' in row:
row = edit_row(row, '/FPGA/FPGA_15_16/')
elif '/PMOD/' in row:
row = edit_row(row, '/PMOD/')
elif '/ETH_PHY/' in row:
row = edit_row(row, '/ETH_PHY/')
elif '/AMC_connector/' in row:
row = edit_row(row, '/AMC_connector/')
elif '/FPGA/FPGA_13_14/' in row:
row = edit_row(row, '/FPGA/FPGA_13_14/')
elif '/FMC_2/' in row:
row = edit_row(row, '/FMC_2/')
elif '/FMC_1/' in row:
row = edit_row(row, '/FMC_1/')
elif '/FPGA/FPGA_PWR&MISC/' in row:
if 'ADC' in row:
continue
row = edit_row(row, '/FPGA/FPGA_PWR&MISC/')
elif '/FPGA/' in row:
row = edit_row(row, '/FPGA/')
elif '/' in row:
row = edit_row(row, '/')
elif 'FMC1' in row:
row = edit_row(row, 'FMC1')
elif 'FMC2' in row:
row = edit_row(row, 'FMC2')
f.write(row + '\n')
cnt += 1
elif False:
print("I " + row.strip())
f.close()
print('Added {} lines to xdc file {}'.format(cnt, out_file))
if __name__ == "__main__":
main(sys.argv[1])