2021-07-08 20:59:28 +02:00
|
|
|
#!/usr/bin/env python3
|
2025-05-11 08:23:41 +02:00
|
|
|
|
2021-07-08 20:59:28 +02:00
|
|
|
import os
|
|
|
|
|
|
2025-05-11 08:23:41 +02:00
|
|
|
from edalize.edatool import get_edatool
|
|
|
|
|
|
|
|
|
|
packages = {
|
|
|
|
|
"Artix": {
|
|
|
|
|
"xc7a12t" : ["cpg238", "csg325"],
|
|
|
|
|
"xc7a15t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
|
|
|
|
|
"xc7a25t" : ["cpg238", "csg325"],
|
|
|
|
|
"xc7a35t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
|
|
|
|
|
"xc7a50t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
|
|
|
|
|
"xc7a75t" : ["csg324", "ftg256", "fgg484", "fgg676"],
|
|
|
|
|
"xc7a100t" : ["csg324", "ftg256", "fgg484", "fgg676"],
|
|
|
|
|
"xc7a200t" : ["sbg484", "fbg484", "fbg676", "ffg1156"],
|
|
|
|
|
},
|
|
|
|
|
"Spartan 7": {
|
|
|
|
|
"xc7s6" : ["ftgb196", "cpga196", "csga225"],
|
|
|
|
|
"xc7s15" : ["ftgb196", "cpga196", "csga225"],
|
|
|
|
|
"xc7s25" : ["ftgb196", "csga225", "csga324"],
|
|
|
|
|
"xc7s50" : ["ftgb196", "csga324", "fgga484"],
|
|
|
|
|
"xc7s75" : ["fgga484", "fgga676"],
|
|
|
|
|
"xc7s100" : ["fgga484", "fgga676"],
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-08 20:59:28 +02:00
|
|
|
if len(os.sys.argv) != 2:
|
|
|
|
|
print("missing board param")
|
|
|
|
|
os.sys.exit()
|
|
|
|
|
part = os.sys.argv[1]
|
|
|
|
|
|
|
|
|
|
build_dir="tmp_" + part
|
|
|
|
|
if not os.path.isdir(build_dir):
|
|
|
|
|
try:
|
|
|
|
|
os.mkdir(build_dir)
|
|
|
|
|
except OSError:
|
|
|
|
|
print ("Creation of the directory %s failed" % build_dir)
|
|
|
|
|
else:
|
|
|
|
|
print ("Successfully created the directory %s " % build_dir)
|
|
|
|
|
|
2025-05-11 08:23:41 +02:00
|
|
|
currDir = os.path.abspath(os.path.curdir) + '/'
|
|
|
|
|
files = []
|
2021-07-10 08:20:27 +02:00
|
|
|
parameters = {}
|
2025-05-11 08:23:41 +02:00
|
|
|
pkg_name = None
|
2021-07-08 20:59:28 +02:00
|
|
|
|
|
|
|
|
subpart = part[0:4].lower()
|
|
|
|
|
if subpart == '10cl':
|
|
|
|
|
family = "Cyclone 10 LP"
|
|
|
|
|
tool = "quartus"
|
|
|
|
|
elif subpart == 'ep4c':
|
|
|
|
|
family = "Cyclone IV E"
|
|
|
|
|
tool = "quartus"
|
|
|
|
|
elif subpart[0:2] == '5c':
|
|
|
|
|
family = "Cyclone V"
|
|
|
|
|
tool = "quartus"
|
2021-07-10 08:20:27 +02:00
|
|
|
files.append({'name': currDir + 'constr_cycloneV.tcl',
|
|
|
|
|
'file_type': 'tclSource'})
|
2024-10-10 19:59:31 +02:00
|
|
|
elif subpart[0:2] == '5s':
|
|
|
|
|
family = "Stratix V"
|
|
|
|
|
tool = "quartus"
|
|
|
|
|
files.append({'name': currDir + 'constr_cycloneV.tcl',
|
|
|
|
|
'file_type': 'tclSource'})
|
2021-07-08 20:59:28 +02:00
|
|
|
elif subpart == "xc7a":
|
|
|
|
|
family = "Artix"
|
2025-05-11 08:23:41 +02:00
|
|
|
tool = "vivado"
|
|
|
|
|
model = subpart
|
2023-03-23 12:00:54 +01:00
|
|
|
elif subpart == "xc7v":
|
|
|
|
|
family = "Virtex 7"
|
|
|
|
|
tool = "vivado"
|
2022-02-22 18:01:02 +01:00
|
|
|
elif subpart == "xc7k":
|
2022-05-14 04:38:58 +02:00
|
|
|
device_size = int(part.split('k')[1].split('t')[0])
|
|
|
|
|
if device_size <= 160:
|
|
|
|
|
family = "Kintex 7"
|
|
|
|
|
tool = "vivado"
|
|
|
|
|
else:
|
|
|
|
|
family = "Kintex7"
|
|
|
|
|
tool = "ise"
|
|
|
|
|
speed = -2
|
2021-07-08 20:59:28 +02:00
|
|
|
elif subpart == "xc7s":
|
|
|
|
|
family = "Spartan 7"
|
2025-05-11 08:23:41 +02:00
|
|
|
tool = "vivado"
|
|
|
|
|
model = subpart
|
2021-07-08 20:59:28 +02:00
|
|
|
elif subpart == "xc6s":
|
2021-07-11 08:57:46 +02:00
|
|
|
family = "Spartan6"
|
2021-07-08 20:59:28 +02:00
|
|
|
tool = "ise"
|
2022-03-25 21:29:00 +01:00
|
|
|
speed = -3
|
|
|
|
|
elif subpart == "xc3s":
|
|
|
|
|
family = "Spartan3E"
|
|
|
|
|
tool = "ise"
|
|
|
|
|
speed = -4
|
2024-02-27 15:44:14 +01:00
|
|
|
elif subpart == "xc6v":
|
|
|
|
|
family = "Virtex6"
|
|
|
|
|
tool = "ise"
|
|
|
|
|
speed = -1
|
2025-05-10 07:02:21 +02:00
|
|
|
elif subpart in ["xcvu", "xcku", "xcau"]:
|
2023-03-09 20:48:19 +01:00
|
|
|
family = "Xilinx UltraScale"
|
2023-01-21 14:00:20 +01:00
|
|
|
tool = "vivado"
|
2021-07-08 20:59:28 +02:00
|
|
|
else:
|
|
|
|
|
print("Error: unknown device")
|
|
|
|
|
os.sys.exit()
|
|
|
|
|
|
2025-05-11 08:23:41 +02:00
|
|
|
if model in ["xc7a", "xc7s"]:
|
|
|
|
|
pkg = packages[family][part][0]
|
|
|
|
|
pkg_name = f"{model}_{pkg}"
|
|
|
|
|
|
2021-07-08 20:59:28 +02:00
|
|
|
if tool in ["ise", "vivado"]:
|
|
|
|
|
pkg_name = {
|
2022-03-25 21:29:00 +01:00
|
|
|
"xc3s500evq100" : "xc3s_vq100",
|
2022-12-04 11:18:44 +01:00
|
|
|
"xc6slx9tqg144" : "xc6s_tqg144",
|
2023-04-17 06:51:02 +02:00
|
|
|
"xc6slx9csg324" : "xc6s_csg324",
|
2022-01-15 11:46:32 +01:00
|
|
|
"xc6slx16ftg256" : "xc6s_ftg256",
|
2022-01-27 09:19:55 +01:00
|
|
|
"xc6slx16csg324" : "xc6s_csg324",
|
2024-08-03 11:01:26 +02:00
|
|
|
"xc6slx25csg324" : "xc6s_csg324",
|
2024-08-03 08:53:18 +02:00
|
|
|
"xc6slx25tcsg324" : "xc6s_t_csg324",
|
2021-07-11 08:57:46 +02:00
|
|
|
"xc6slx45csg324" : "xc6s_csg324",
|
2024-03-28 22:14:27 +01:00
|
|
|
"xc6slx45tfgg484" : "xc6s_t_fgg484",
|
2021-07-11 08:57:46 +02:00
|
|
|
"xc6slx100fgg484" : "xc6s_fgg484",
|
2023-02-16 19:51:04 +01:00
|
|
|
"xc6slx150tcsg484" : "xc6s_csg484",
|
2024-02-28 12:52:01 +01:00
|
|
|
"xc6slx150tfgg484" : "xc6s_t_fgg484",
|
2024-02-27 15:44:14 +01:00
|
|
|
"xc6vlx130tff784" : "xc6v_ff784",
|
2022-08-23 17:13:13 +02:00
|
|
|
"xc7k70tfbg484" : "xc7k_fbg484",
|
2023-11-09 01:45:46 +01:00
|
|
|
"xc7k70tfbg676" : "xc7k_fbg676",
|
2022-05-14 09:30:01 +02:00
|
|
|
"xc7k160tffg676" : "xc7k_ffg676",
|
2022-02-22 18:01:02 +01:00
|
|
|
"xc7k325tffg676" : "xc7k_ffg676",
|
|
|
|
|
"xc7k325tffg900" : "xc7k_ffg900",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc7k420tffg901" : "xc7k_ffg901",
|
2023-03-23 12:00:54 +01:00
|
|
|
"xc7vx330tffg1157" : "xc7v_ffg1157",
|
2024-09-22 13:02:37 +02:00
|
|
|
"xcku040-ffva1156" : "xcku040_ffva1156",
|
|
|
|
|
"xcku060-ffva1156" : "xcku060_ffva1156",
|
|
|
|
|
"xcvu9p-flga2104" : "xcvu9p_flga2104",
|
2023-02-20 08:41:48 +01:00
|
|
|
"xcvu37p-fsvh2892" : "xcvu37p_fsvh2892",
|
2024-09-22 13:02:37 +02:00
|
|
|
"xcku3p-ffva676" : "xcku3p_ffva676",
|
|
|
|
|
"xcku5p-ffvb676" : "xcku5p_ffvb676",
|
2025-05-10 07:02:21 +02:00
|
|
|
"xcau15p-ffvb676" : "xcau15p_ffvb676",
|
2025-05-11 08:23:41 +02:00
|
|
|
}.get(part, pkg_name)
|
2021-07-08 20:59:28 +02:00
|
|
|
if tool == "ise":
|
|
|
|
|
cst_type = "UCF"
|
2021-07-11 08:57:46 +02:00
|
|
|
tool_options = {'family': family,
|
|
|
|
|
'device': {
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc3s500evq100": "xc3s500e",
|
2022-12-04 11:18:44 +01:00
|
|
|
"xc6slx9tqg144": "xc6slx9",
|
2023-04-17 06:51:02 +02:00
|
|
|
"xc6slx9csg324": "xc6slx9",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx16ftg256": "xc6slx16",
|
|
|
|
|
"xc6slx16csg324": "xc6slx16",
|
2024-08-03 11:01:26 +02:00
|
|
|
"xc6slx25csg324": "xc6slx25",
|
2024-08-03 08:53:18 +02:00
|
|
|
"xc6slx25tcsg324": "xc6slx25t",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx45csg324": "xc6slx45",
|
2024-03-28 22:14:27 +01:00
|
|
|
"xc6slx45tfgg484": "xc6slx45t",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx100fgg484": "xc6slx100",
|
2023-02-16 19:51:04 +01:00
|
|
|
"xc6slx150tcsg484": "xc6slx150t",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx150tfgg484": "xc6slx150t",
|
2024-02-27 15:44:14 +01:00
|
|
|
"xc6vlx130tff784": "xc6vlx130t",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc7k325tffg676": "xc7k325t",
|
|
|
|
|
"xc7k325tffg900": "xc7k325t",
|
|
|
|
|
"xc7k420tffg901": "xc7k420t",
|
|
|
|
|
}[part],
|
2021-07-11 08:57:46 +02:00
|
|
|
'package': {
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc3s500evq100": "vq100",
|
2022-12-04 11:18:44 +01:00
|
|
|
"xc6slx9tqg144": "tqg144",
|
2023-04-17 06:51:02 +02:00
|
|
|
"xc6slx9csg324": "csg324",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx16ftg256": "ftg256",
|
|
|
|
|
"xc6slx16csg324": "csg324",
|
2024-08-03 11:01:26 +02:00
|
|
|
"xc6slx25csg324": "csg324",
|
2024-08-03 08:53:18 +02:00
|
|
|
"xc6slx25tcsg324": "csg324",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx45csg324": "csg324",
|
2024-03-28 22:14:27 +01:00
|
|
|
"xc6slx45tfgg484": "fgg484",
|
2024-02-27 13:30:33 +01:00
|
|
|
"xc6slx100fgg484": "fgg484",
|
2023-02-16 19:51:04 +01:00
|
|
|
"xc6slx150tcsg484": "csg484",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc6slx150tfgg484": "fgg484",
|
2024-02-27 15:44:14 +01:00
|
|
|
"xc6vlx130tff784": "ff784",
|
2022-05-14 04:38:58 +02:00
|
|
|
"xc7k325tffg676": "ffg676",
|
|
|
|
|
"xc7k325tffg900": "ffg900",
|
|
|
|
|
"xc7k420tffg901": "ffg901",
|
|
|
|
|
}[part],
|
2022-03-25 21:29:00 +01:00
|
|
|
'speed' : speed
|
2021-07-11 08:57:46 +02:00
|
|
|
}
|
2021-07-08 20:59:28 +02:00
|
|
|
else:
|
|
|
|
|
cst_type = "xdc"
|
2025-05-11 08:23:41 +02:00
|
|
|
# Artix/Spartan 7 Specific use case:
|
|
|
|
|
if family in ["Artix", "Spartan 7"]:
|
|
|
|
|
tool_options = {'part': f"{part}{pkg}-1"}
|
|
|
|
|
elif family == "Xilinx UltraScale":
|
2023-03-09 20:48:19 +01:00
|
|
|
if part in ["xcvu9p-flga2104", "xcku5p-ffvb676"]:
|
|
|
|
|
tool_options = {'part': part + '-1-e'}
|
2023-02-20 08:41:48 +01:00
|
|
|
parameters["secondaryflash"]= {
|
|
|
|
|
'datatype': 'int',
|
|
|
|
|
'paramtype': 'vlogdefine',
|
|
|
|
|
'description': 'secondary flash',
|
|
|
|
|
'default': 1}
|
2023-10-12 18:02:23 +02:00
|
|
|
elif part == "xcku3p-ffva676":
|
|
|
|
|
tool_options = {'part': part + '-2-e'}
|
2023-02-20 08:41:48 +01:00
|
|
|
elif part == "xcvu37p-fsvh2892":
|
|
|
|
|
tool_options = {'part': part + '-2L-e'}
|
2024-09-22 13:02:37 +02:00
|
|
|
elif part in ["xcku040-ffva1156", "xcku060-ffva1156"]:
|
|
|
|
|
tool_options = {'part': part + '-2-e'}
|
|
|
|
|
parameters["secondaryflash"]= {
|
|
|
|
|
'datatype': 'int',
|
|
|
|
|
'paramtype': 'vlogdefine',
|
|
|
|
|
'description': 'secondary flash',
|
|
|
|
|
'default': 1}
|
2025-05-10 07:02:21 +02:00
|
|
|
elif part == "xcau15p-ffvb676":
|
|
|
|
|
tool_options = {'part': part + '-2-e'}
|
2023-01-21 14:00:20 +01:00
|
|
|
else:
|
|
|
|
|
tool_options = {'part': part + '-1'}
|
2025-05-11 08:23:41 +02:00
|
|
|
|
2021-07-11 08:57:46 +02:00
|
|
|
cst_file = currDir + "constr_" + pkg_name + "." + cst_type.lower()
|
2021-07-08 20:59:28 +02:00
|
|
|
files.append({'name': currDir + 'xilinx_spiOverJtag.v',
|
|
|
|
|
'file_type': 'verilogSource'})
|
|
|
|
|
files.append({'name': cst_file, 'file_type': cst_type})
|
|
|
|
|
else:
|
|
|
|
|
full_part = {
|
2024-04-27 04:46:51 +02:00
|
|
|
"10cl016484" : "10CL016YU484C8G",
|
|
|
|
|
"10cl025256" : "10CL025YU256C8G",
|
|
|
|
|
"10cl055484" : "10CL055YU484C8G",
|
|
|
|
|
"ep4cgx15027": "EP4CGX150DF27I7",
|
|
|
|
|
"ep4ce11523" : "EP4CE115F23C7",
|
|
|
|
|
"ep4ce2217" : "EP4CE22F17C6",
|
|
|
|
|
"ep4ce1523" : "EP4CE15F23C8",
|
2024-04-30 20:51:29 +02:00
|
|
|
"ep4ce1017" : "EP4CE10F17C8",
|
|
|
|
|
"ep4ce622" : "EP4CE6E22C8",
|
2024-08-25 06:32:00 +02:00
|
|
|
"5ce215" : "5CEBA2U15C8",
|
2024-04-27 04:46:51 +02:00
|
|
|
"5ce223" : "5CEFA2F23I7",
|
|
|
|
|
"5ce523" : "5CEFA5F23I7",
|
|
|
|
|
"5ce423" : "5CEBA4F23C8",
|
|
|
|
|
"5ce927" : "5CEBA9F27C7",
|
|
|
|
|
"5cse423" : "5CSEMA4U23C6",
|
2024-10-10 19:59:31 +02:00
|
|
|
"5cse623" : "5CSEBA6U23I7",
|
|
|
|
|
"5sgsd5" : "5SGSMD5K2F40I3"}[part]
|
2021-07-08 20:59:28 +02:00
|
|
|
files.append({'name': currDir + 'altera_spiOverJtag.v',
|
|
|
|
|
'file_type': 'verilogSource'})
|
2021-11-28 10:00:21 +01:00
|
|
|
files.append({'name': currDir + 'altera_spiOverJtag.sdc',
|
2021-07-08 20:59:28 +02:00
|
|
|
'file_type': 'SDC'})
|
|
|
|
|
tool_options = {'device': full_part, 'family':family}
|
|
|
|
|
|
2025-05-11 08:09:02 +02:00
|
|
|
files.append({'name': currDir + 'spiOverJtag_core.v',
|
|
|
|
|
'file_type': 'verilogSource'})
|
|
|
|
|
|
2021-07-08 20:59:28 +02:00
|
|
|
parameters[family.lower().replace(' ', '')]= {
|
|
|
|
|
'datatype': 'int',
|
|
|
|
|
'paramtype': 'vlogdefine',
|
|
|
|
|
'description': 'fpga family',
|
|
|
|
|
'default': 1}
|
|
|
|
|
|
|
|
|
|
edam = {'name' : "spiOverJtag",
|
|
|
|
|
'files': files,
|
|
|
|
|
'tool_options': {tool: tool_options},
|
|
|
|
|
'parameters': parameters,
|
|
|
|
|
'toplevel' : 'spiOverJtag',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
backend = get_edatool(tool)(edam=edam, work_root=build_dir)
|
|
|
|
|
backend.configure()
|
|
|
|
|
backend.build()
|
2021-07-11 08:57:46 +02:00
|
|
|
|
|
|
|
|
if tool == "vivado":
|
|
|
|
|
import shutil
|
2025-05-11 08:23:41 +02:00
|
|
|
import subprocess
|
|
|
|
|
import gzip
|
|
|
|
|
|
|
|
|
|
# Compress bitstream.
|
|
|
|
|
with open(f"tmp_{part}/spiOverJtag.bit", 'rb') as bit:
|
|
|
|
|
with gzip.open(f"spiOverJtag_{part}.bit.gz", 'wb', compresslevel=9) as bit_gz:
|
|
|
|
|
shutil.copyfileobj(bit, bit_gz)
|
|
|
|
|
|
|
|
|
|
# Create Symbolic links for all supported packages.
|
|
|
|
|
if family in ["Artix", "Spartan 7"]:
|
|
|
|
|
in_file = f"spiOverJtag_{part}.bit.gz"
|
|
|
|
|
for pkg in packages[family][part]:
|
|
|
|
|
out_file = f"spiOverJtag_{part}{pkg}.bit.gz"
|
|
|
|
|
if not os.path.exists(out_file):
|
|
|
|
|
subprocess.run(["ln", "-s", in_file, out_file])
|