Moved to more fusesoc like build style
Signed-off-by: Joppe Blondel <joppe@blondel.nl>
This commit is contained in:
@ -10,17 +10,21 @@ port = 2020
|
||||
privkey = /home/joppe/.ssh/id_rsa
|
||||
pubkey = /home/joppe/.ssh/id_rsa.pub
|
||||
|
||||
[target:default]
|
||||
[target.synth]
|
||||
toolchain = ISE
|
||||
|
||||
# Toolchain settings
|
||||
family = spartan6
|
||||
device = xc6slx9
|
||||
package = tqg144
|
||||
speedgrade = -2
|
||||
toolchain = ISE
|
||||
|
||||
[build:default]
|
||||
target = default
|
||||
toplevel = toplevel
|
||||
constraints = CON/toplevel.ucf
|
||||
src_vhdl = RTL/toplevel.vhd
|
||||
src_verilog =
|
||||
src_sysverilog =
|
||||
#xst_opts =
|
||||
#ngdbuild_opts =
|
||||
#map_opts =
|
||||
#par_opts =
|
||||
|
||||
# Fileset
|
||||
files_vhdl = RTL/toplevel.vhd
|
||||
#files_verilog =
|
||||
files_con = CON/toplevel.ucf
|
@ -1,126 +0,0 @@
|
||||
from asyncio import constants
|
||||
import threading
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import signal
|
||||
import random
|
||||
|
||||
def needed_files(config, target) -> list:
|
||||
if not config.has_section(f'build:{target}'):
|
||||
print("ERROR: config file has no build section for target")
|
||||
return None
|
||||
outdir = f"{config.get('project', 'out_dir', fallback='out')}"
|
||||
needed_files = [
|
||||
f'{outdir}/{target}/synth.ngc',
|
||||
]
|
||||
for s in config.get(f'build:{target}', 'constraints', fallback="").split():
|
||||
needed_files.append(s)
|
||||
return needed_files
|
||||
|
||||
def generated_files(config, target) -> list:
|
||||
outdir = f"{config.get('project', 'out_dir', fallback='out')}"
|
||||
return [
|
||||
f'{outdir}/{target}/impl-ngd.log',
|
||||
f'{outdir}/{target}/impl-map.log',
|
||||
f'{outdir}/{target}/impl-par.log',
|
||||
f'{outdir}/{target}/netgen.log',
|
||||
f'{outdir}/{target}/{target}.v',
|
||||
f'{outdir}/{target}/{target}.sdf',
|
||||
f'{outdir}/{target}/impl.ncd',
|
||||
f'{outdir}/{target}/impl.pcf',
|
||||
]
|
||||
|
||||
def do(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log("Implement:")
|
||||
|
||||
if not config.has_section(f'build:{target}'):
|
||||
log("ERROR: config file has no build section for target")
|
||||
return 1
|
||||
|
||||
devtarget = f'target:{config.get(f"build:{target}", "target", fallback="")}'
|
||||
if not config.has_section(devtarget):
|
||||
log("ERROR: config file has no section for device target")
|
||||
return 1
|
||||
|
||||
device = f"{config.get(devtarget, 'device', fallback='')}{config.get(devtarget, 'speedgrade', fallback='')}-{config.get(devtarget, 'package', fallback='')}"
|
||||
builddir = f"{prefix}/{config.get('project', 'build_dir', fallback='.build')}"
|
||||
outdir = f"{prefix}/{config.get('project', 'out_dir', fallback='out')}"
|
||||
|
||||
os.makedirs(builddir, exist_ok=True)
|
||||
curdir = f"{os.getcwd()}/{prefix}"
|
||||
|
||||
contstraints = []
|
||||
for s in config.get(f'build:{target}', 'constraints', fallback="").split():
|
||||
contstraints.append(f"{curdir}/{s}")
|
||||
|
||||
log(" - Executing ngdbuild")
|
||||
p = subprocess.Popen(f"ngdbuild -intstyle xflow -p {device} -uc {contstraints[0]} {curdir}/{outdir}/{target}/synth.ngc impl.ngd", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
if res:
|
||||
log(" - ERROR: return code is", res)
|
||||
log(" - copy log")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log')
|
||||
return res
|
||||
|
||||
log(" - Executing map")
|
||||
p = subprocess.Popen(f"map -intstyle xflow -p {device} -detail -ol high -xe n -w impl.ngd -o impl.map.ncd impl.pcf", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
if res:
|
||||
log(" - ERROR: return code is", res)
|
||||
log(" - copy log")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log')
|
||||
shutil.copy(f'{builddir}/impl.map.mrp', f'{outdir}/{target}/impl-map.log')
|
||||
return res
|
||||
|
||||
log(" - Executing par")
|
||||
p = subprocess.Popen(f"par -intstyle xflow -ol high -xe n -w impl.map.ncd impl.pcf | tee impl.par.log", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
if res:
|
||||
log(" - ERROR: return code is", res)
|
||||
log(" - copy log")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log')
|
||||
shutil.copy(f'{builddir}/impl.map.mrp', f'{outdir}/{target}/impl-map.log')
|
||||
shutil.copy(f'{builddir}/impl.par.log', f'{outdir}/{target}/impl-par.log')
|
||||
return res
|
||||
|
||||
log(" - Executing netgen")
|
||||
p = subprocess.Popen(f"netgen -intstyle xflow -sim -ofmt verilog -w -insert_glbl true -sdf_anno true -ism impl.map.ncd > netgen.log", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
if res:
|
||||
log(" - ERROR: return code is", res)
|
||||
log(" - copy log")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log')
|
||||
shutil.copy(f'{builddir}/impl.map.mrp', f'{outdir}/{target}/impl-map.log')
|
||||
shutil.copy(f'{builddir}/impl.par.log', f'{outdir}/{target}/impl-par.log')
|
||||
shutil.copy(f'{builddir}/netgen.log', f'{outdir}/{target}/netgen.log')
|
||||
return res
|
||||
|
||||
log(" - copy output files")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log')
|
||||
shutil.copy(f'{builddir}/impl.map.mrp', f'{outdir}/{target}/impl-map.log')
|
||||
shutil.copy(f'{builddir}/impl.par.log', f'{outdir}/{target}/impl-par.log')
|
||||
shutil.copy(f'{builddir}/impl.pcf', f'{outdir}/{target}/impl.pcf')
|
||||
shutil.copy(f'{builddir}/impl.pcf.ncd', f'{outdir}/{target}/impl.ncd')
|
||||
shutil.copy(f'{builddir}/impl.map.v', f'{outdir}/{target}/{target}.v')
|
||||
shutil.copy(f'{builddir}/impl.map.sdf', f'{outdir}/{target}/{target}.sdf')
|
||||
shutil.copy(f'{builddir}/netgen.log', f'{outdir}/{target}/netgen.log')
|
||||
return 0
|
@ -1,80 +0,0 @@
|
||||
import threading
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import signal
|
||||
import random
|
||||
|
||||
def needed_files(config, target) -> list:
|
||||
if not config.has_section(f'build:{target}'):
|
||||
print("ERROR: config file has no build section for target")
|
||||
return None
|
||||
needed_files = []
|
||||
for s in config.get(f'build:{target}', 'src_vhdl', fallback="").split():
|
||||
needed_files.append(s)
|
||||
for s in config.get(f'build:{target}', 'src_verilog', fallback="").split():
|
||||
needed_files.append(s)
|
||||
for s in config.get(f'build:{target}', 'src_sysverilog', fallback="").split():
|
||||
needed_files.append(s)
|
||||
return needed_files
|
||||
|
||||
def generated_files(config, target) -> list:
|
||||
outdir = f"{config.get('project', 'out_dir', fallback='out')}"
|
||||
return [
|
||||
f'{outdir}/{target}/synth.log',
|
||||
f'{outdir}/{target}/synth.ngc',
|
||||
]
|
||||
|
||||
def do(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log("Synthesize:")
|
||||
|
||||
if not config.has_section(f'build:{target}'):
|
||||
log("ERROR: config file has no build section for target")
|
||||
return 1
|
||||
|
||||
devtarget = f'target:{config.get(f"build:{target}", "target", fallback="")}'
|
||||
if not config.has_section(devtarget):
|
||||
log("ERROR: config file has no section for device target")
|
||||
return 1
|
||||
|
||||
device = f"{config.get(devtarget, 'device', fallback='')}{config.get(devtarget, 'speedgrade', fallback='')}-{config.get(devtarget, 'package', fallback='')}"
|
||||
builddir = f"{prefix}/{config.get('project', 'build_dir', fallback='.build')}"
|
||||
outdir = f"{prefix}/{config.get('project', 'out_dir', fallback='out')}"
|
||||
|
||||
os.makedirs(builddir, exist_ok=True)
|
||||
curdir = f"{os.getcwd()}/{prefix}"
|
||||
|
||||
log(" - writing project file")
|
||||
with open(f'{builddir}/syn.prj', 'w') as f:
|
||||
for s in config.get(f'build:{target}', 'src_vhdl', fallback="").split():
|
||||
f.write(f"vhdl work {curdir}/{s}\n")
|
||||
for s in config.get(f'build:{target}', 'src_verilog', fallback="").split():
|
||||
f.write(f"verilog work {curdir}/{s}\n")
|
||||
for s in config.get(f'build:{target}', 'src_sysverilog', fallback="").split():
|
||||
f.write(f"verilog work {curdir}/{s}\n")
|
||||
|
||||
log(" - writing project generation file")
|
||||
with open(f'{builddir}/prj.scr', 'w') as f:
|
||||
f.write(f'run\n-ifn syn.prj\n-ofn syn.ngc\n-ifmt mixed\n')
|
||||
f.write(f'-top {config.get(f"sources:{target}", "toplevel", fallback="toplevel")}\n')
|
||||
f.write(f'-p {device}\n-glob_opt max_delay -opt_mode speed')
|
||||
|
||||
log(" - Executing xst")
|
||||
p = subprocess.Popen("xst -intstyle xflow -ifn prj.scr", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
if res:
|
||||
log(" - ERROR: return code is", res)
|
||||
log(" - copy log")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/prj.srp', f'{outdir}/{target}/synth.log')
|
||||
return res
|
||||
|
||||
log(" - copy output files")
|
||||
os.makedirs(f'{outdir}/{target}', exist_ok=True)
|
||||
shutil.copy(f'{builddir}/syn.ngc', f'{outdir}/{target}/synth.ngc')
|
||||
shutil.copy(f'{builddir}/prj.srp', f'{outdir}/{target}/synth.log')
|
||||
return 0
|
35
remotesyn/toolchains/ISE.py
Normal file
35
remotesyn/toolchains/ISE.py
Normal file
@ -0,0 +1,35 @@
|
||||
from .util_ISE.xst import xst
|
||||
from .util_ISE.ngdbuild import ngdbuild
|
||||
from .util_ISE.map import map
|
||||
from .util_ISE.par import par
|
||||
from .util_ISE.netgen import netgen
|
||||
|
||||
def do(config, target, log, subprocesses, prefix='.'):
|
||||
log("Syntesize:")
|
||||
|
||||
res = xst(config, target, log, subprocesses, prefix)
|
||||
if res != 0:
|
||||
print("ERROR: xst returned with", res)
|
||||
return res
|
||||
|
||||
log("Implement")
|
||||
|
||||
res = ngdbuild(config, target, log, subprocesses, prefix)
|
||||
if res != 0:
|
||||
print("ERROR: ngdbuild returned with", res)
|
||||
return res
|
||||
|
||||
res = map(config, target, log, subprocesses, prefix)
|
||||
if res != 0:
|
||||
print("ERROR: map returned with", res)
|
||||
return res
|
||||
|
||||
res = par(config, target, log, subprocesses, prefix)
|
||||
if res != 0:
|
||||
print("ERROR: par returned with", res)
|
||||
return res
|
||||
|
||||
res = netgen(config, target, log, subprocesses, prefix)
|
||||
if res != 0:
|
||||
print("ERROR: netgen returned with", res)
|
||||
return res
|
0
remotesyn/toolchains/util_ISE/__init__.py
Normal file
0
remotesyn/toolchains/util_ISE/__init__.py
Normal file
36
remotesyn/toolchains/util_ISE/map.py
Normal file
36
remotesyn/toolchains/util_ISE/map.py
Normal file
@ -0,0 +1,36 @@
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def map(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log(" - parsing options")
|
||||
device = config.get(f'target.{target}', 'device', fallback='')
|
||||
package = config.get(f'target.{target}', 'package', fallback='')
|
||||
speedgrade = config.get(f'target.{target}', 'speedgrade', fallback='')
|
||||
map_opts = config.get(f'target.{target}', 'map_opts', fallback='')
|
||||
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||
|
||||
devstring = f'{device}{speedgrade}-{package}'
|
||||
prefix = f'{os.getcwd()}/{prefix}'
|
||||
build_dir = f'{prefix}/{build_dir}'
|
||||
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||
|
||||
log(" - creating output directories")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
log(" - run map")
|
||||
p = subprocess.Popen(f"map -intstyle xflow -p {devstring} -detail {map_opts} -ol high -xe n -w {out_dir}/{target}.ngd -o impl.map.ncd impl.pcf",
|
||||
shell=True, cwd=build_dir,
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
|
||||
log(" - copy logs")
|
||||
shutil.copy(f'{build_dir}/impl.map.mrp', f'{out_dir}/map.log')
|
||||
|
||||
return res
|
37
remotesyn/toolchains/util_ISE/netgen.py
Normal file
37
remotesyn/toolchains/util_ISE/netgen.py
Normal file
@ -0,0 +1,37 @@
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def netgen(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log(" - parsing options")
|
||||
netgen_opts = config.get(f'target.{target}', 'netgen_opts', fallback='')
|
||||
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||
|
||||
prefix = f'{os.getcwd()}/{prefix}'
|
||||
build_dir = f'{prefix}/{build_dir}'
|
||||
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||
|
||||
log(" - creating output directories")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
log(" - run netgen")
|
||||
p = subprocess.Popen(f"netgen -intstyle xflow -sim -ofmt verilog -w -insert_glbl true -sdf_anno true {netgen_opts} -ism {out_dir}/{target}.ncd > netgen.log",
|
||||
shell=True, cwd=build_dir,
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
|
||||
log(" - copy logs")
|
||||
shutil.copy(f'{build_dir}/netgen.log', f'{out_dir}/netgen.log')
|
||||
|
||||
if res==0:
|
||||
log(" - copy output files")
|
||||
shutil.copy(f'{build_dir}/{target}.v', f'{out_dir}/{target}.v')
|
||||
shutil.copy(f'{build_dir}/{target}.sdf', f'{out_dir}/{target}.sdf')
|
||||
|
||||
return res
|
41
remotesyn/toolchains/util_ISE/ngdbuild.py
Normal file
41
remotesyn/toolchains/util_ISE/ngdbuild.py
Normal file
@ -0,0 +1,41 @@
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def ngdbuild(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log(" - parsing options")
|
||||
device = config.get(f'target.{target}', 'device', fallback='')
|
||||
package = config.get(f'target.{target}', 'package', fallback='')
|
||||
speedgrade = config.get(f'target.{target}', 'speedgrade', fallback='')
|
||||
ngdbuild_opts = config.get(f'target.{target}', 'ngdbuild_opts', fallback='')
|
||||
files_con = config.get(f'target.{target}', 'files_con', fallback='').split(' ')
|
||||
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||
|
||||
devstring = f'{device}{speedgrade}-{package}'
|
||||
prefix = f'{os.getcwd()}/{prefix}'
|
||||
build_dir = f'{prefix}/{build_dir}'
|
||||
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||
|
||||
log(" - creating output directories")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
log(" - run ngdbuild")
|
||||
p = subprocess.Popen(f"ngdbuild -intstyle xflow -p {devstring} -uc {prefix}/{files_con[0]} {ngdbuild_opts} {out_dir}/{target}.ngc impl.ngd",
|
||||
shell=True, cwd=build_dir,
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
|
||||
log(" - copy logs")
|
||||
shutil.copy(f'{build_dir}/impl.bld', f'{out_dir}/ngdbuild.log')
|
||||
|
||||
if res==0:
|
||||
log(" - copy output files")
|
||||
shutil.copy(f'{build_dir}/impl.ngd', f'{out_dir}/{target}.ngd')
|
||||
|
||||
return res
|
41
remotesyn/toolchains/util_ISE/par.py
Normal file
41
remotesyn/toolchains/util_ISE/par.py
Normal file
@ -0,0 +1,41 @@
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def par(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log(" - parsing options")
|
||||
device = config.get(f'target.{target}', 'device', fallback='')
|
||||
package = config.get(f'target.{target}', 'package', fallback='')
|
||||
speedgrade = config.get(f'target.{target}', 'speedgrade', fallback='')
|
||||
par_opts = config.get(f'target.{target}', 'par_opts', fallback='')
|
||||
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||
|
||||
devstring = f'{device}{speedgrade}-{package}'
|
||||
prefix = f'{os.getcwd()}/{prefix}'
|
||||
build_dir = f'{prefix}/{build_dir}'
|
||||
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||
|
||||
log(" - creating output directories")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
log(" - run par")
|
||||
p = subprocess.Popen(f"par -intstyle xflow -ol high -xe n {par_opts} -w impl.map.ncd impl.pcf | tee par.log",
|
||||
shell=True, cwd=build_dir,
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
|
||||
log(" - copy logs")
|
||||
shutil.copy(f'{build_dir}/par.log', f'{out_dir}/par.log')
|
||||
|
||||
if res==0:
|
||||
log(" - copy output files")
|
||||
shutil.copy(f'{build_dir}/impl.pcf', f'{out_dir}/{target}.pcf')
|
||||
shutil.copy(f'{build_dir}/impl.pcf.ncd', f'{out_dir}/{target}.ncd')
|
||||
|
||||
return res
|
60
remotesyn/toolchains/util_ISE/xst.py
Normal file
60
remotesyn/toolchains/util_ISE/xst.py
Normal file
@ -0,0 +1,60 @@
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
def xst(config, target, log, subprocesses, prefix='.') -> int:
|
||||
log(" - parsing options")
|
||||
device = config.get(f'target.{target}', 'device', fallback='')
|
||||
package = config.get(f'target.{target}', 'package', fallback='')
|
||||
speedgrade = config.get(f'target.{target}', 'speedgrade', fallback='')
|
||||
toplevel = config.get(f'target.{target}', 'toplevel', fallback='toplevel')
|
||||
xst_opts = config.get(f'target.{target}', 'xst_opts', fallback='')
|
||||
files_vhdl = config.get(f'target.{target}', 'files_vhdl', fallback='').split(' ')
|
||||
files_verilog = config.get(f'target.{target}', 'files_verilog', fallback='').split(' ')
|
||||
build_dir = config.get(f'project', 'build_dir', fallback='build')
|
||||
out_dir = config.get(f'project', 'out_dir', fallback='out')
|
||||
|
||||
devstring = f'{device}{speedgrade}-{package}'
|
||||
prefix = f'{os.getcwd()}/{prefix}'
|
||||
build_dir = f'{prefix}/{build_dir}'
|
||||
out_dir = f'{prefix}/{out_dir}/{target}'
|
||||
|
||||
log(" - creating output directories")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
log(" - writing project file")
|
||||
with open(f'{build_dir}/syn.prj', 'w') as f:
|
||||
for s in files_vhdl:
|
||||
if s=='':
|
||||
continue
|
||||
f.write(f"vhdl work {prefix}/{s}\n")
|
||||
for s in files_verilog:
|
||||
if s=='':
|
||||
continue
|
||||
f.write(f"verilog work {prefix}/{s}\n")
|
||||
|
||||
log(" - writing project generation file")
|
||||
with open(f'{build_dir}/prj.scr', 'w') as f:
|
||||
f.write(f'run\n-ifn syn.prj\n-ofn syn.ngc\n-ifmt mixed\n')
|
||||
f.write(f'-top {toplevel}\n')
|
||||
f.write(f'-p {devstring}\n-glob_opt max_delay -opt_mode speed')
|
||||
|
||||
log(" - run xst")
|
||||
p = subprocess.Popen(f"xst -intstyle xflow {xst_opts} -ifn prj.scr",
|
||||
shell=True, cwd=build_dir,
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocesses.append(p)
|
||||
while p.poll() is None:
|
||||
time.sleep(1)
|
||||
res = p.returncode
|
||||
|
||||
log(" - copy logs")
|
||||
shutil.copy(f'{build_dir}/prj.srp', f'{out_dir}/xst.log')
|
||||
|
||||
if res==0:
|
||||
log(" - copy output files")
|
||||
shutil.copy(f'{build_dir}/syn.ngc', f'{out_dir}/{target}.ngc')
|
||||
|
||||
return res
|
@ -5,34 +5,24 @@ import sys
|
||||
|
||||
def print_help():
|
||||
print("Unified FPGA synthesizer frontend\r\n(c) Joppe Blondel - 2022\r\n")
|
||||
print(f"Usage: {sys.argv[0]} [ OPTIONS ] action [ target ] ...")
|
||||
print(f"Usage: {sys.argv[0]} [ OPTIONS ] target")
|
||||
print("")
|
||||
print("Options:")
|
||||
print(" -h Show this help message")
|
||||
print(" -c <file> Configuration file, defaults to project.cfg")
|
||||
print("")
|
||||
print("Actions:")
|
||||
print("ip <target> Generate IP files from vendor provided libraries")
|
||||
print("syn <target> Synthesize design for target")
|
||||
print("impl <target> Route and place design for target")
|
||||
print("bit <target> Generate output files and run analysis for target")
|
||||
print("all <target> Generate IP, synthesize, route and place design for target")
|
||||
print("floorplan <target> Run floorplan editor, currently only for local execution")
|
||||
print("sim <simtarget> Run simulation target")
|
||||
|
||||
if __name__=="__main__":
|
||||
# Parse arguments
|
||||
i = 1
|
||||
nextarg = None
|
||||
configpath = 'project.cfg'
|
||||
actions = []
|
||||
target = ''
|
||||
while i<len(sys.argv):
|
||||
if nextarg is not None:
|
||||
if nextarg=='config':
|
||||
configpath = sys.argv[i]
|
||||
nextarg = None
|
||||
else:
|
||||
actions.append((nextarg, sys.argv[i]))
|
||||
nextarg = None
|
||||
elif sys.argv[i]=='-h':
|
||||
print_help()
|
||||
@ -40,7 +30,7 @@ if __name__=="__main__":
|
||||
elif sys.argv[i]=='-c':
|
||||
nextarg = 'config'
|
||||
else:
|
||||
nextarg = sys.argv[i]
|
||||
target = sys.argv[i]
|
||||
i += 1
|
||||
if nextarg is not None:
|
||||
print("ERROR: expected more arguments")
|
||||
@ -52,26 +42,16 @@ if __name__=="__main__":
|
||||
subprocesses = []
|
||||
|
||||
try:
|
||||
for action in actions:
|
||||
target = action[1]
|
||||
action = action[0]
|
||||
|
||||
if not config.has_section(f'build:{target}'):
|
||||
print("ERROR: config file has no build section for target")
|
||||
exit(1)
|
||||
devtarget = f'target:{config.get(f"build:{target}", "target", fallback="")}'
|
||||
if not config.has_section(devtarget):
|
||||
print("ERROR: config file has no section for device target")
|
||||
exit(1)
|
||||
toolchain = config.get(devtarget, 'toolchain', fallback="NONE")
|
||||
if toolchain=="NONE":
|
||||
print("ERROR: no toolchain specified for device target")
|
||||
toolchain = config.get(f'target.{target}', 'toolchain', fallback='NONE')
|
||||
if toolchain=='NONE':
|
||||
print("ERROR: No toolchain specified for target")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
exec(f"from remotesyn.{toolchain}.{action} import do")
|
||||
exec(f"from remotesyn.toolchains.{toolchain} import do")
|
||||
except ImportError:
|
||||
print(f"ERROR: Unknown action '{action}' for toolchain '{toolchain}'")
|
||||
print(f"ERROR: Unknown toolchain '{toolchain}'")
|
||||
exit(1)
|
||||
|
||||
ret = do(config, target, print, subprocesses)
|
||||
|
@ -64,6 +64,25 @@ def recv_file(channel, file):
|
||||
f.write(channel.recv(1024))
|
||||
fsize -= 1024
|
||||
|
||||
def recv_dir(channel, dr):
|
||||
cmd(b'ls'+sstr(dr), channel)
|
||||
while True:
|
||||
status = channel.recv(2)
|
||||
if status != b'\x00\x00':
|
||||
break
|
||||
if status!=b'OK':
|
||||
msg = channel.recv(1024)
|
||||
print("Error:", bytes.decode(msg, 'ascii'))
|
||||
exit(1)
|
||||
ls = rstr(channel)
|
||||
for p in ls.split('\n'):
|
||||
tp = p[0]
|
||||
name = p[1:]
|
||||
if tp=='d':
|
||||
recv_dir(channel, f'{dr}/{name}')
|
||||
else:
|
||||
recv_file(channel, f'{dr}/{name}')
|
||||
|
||||
def print_help():
|
||||
print("Unified FPGA synthesizer frontend - remote execution\r\n(c) Joppe Blondel - 2022\r\n")
|
||||
print(f"Usage: {sys.argv[0]} [ OPTIONS ] action [ target ] ...")
|
||||
@ -71,29 +90,19 @@ def print_help():
|
||||
print("Options:")
|
||||
print(" -h Show this help message")
|
||||
print(" -c <file> Configuration file, defaults to project.cfg")
|
||||
print("")
|
||||
print("Actions:")
|
||||
print("ip <target> Generate IP files from vendor provided libraries")
|
||||
print("syn <target> Synthesize design for target")
|
||||
print("impl <target> Route and place design for target")
|
||||
print("bit <target> Generate output files and run analysis for target")
|
||||
print("all <target> Generate IP, synthesize, route and place design for target")
|
||||
print("floorplan <target> Run floorplan editor, currently only for local execution")
|
||||
print("sim <simtarget> Run simulation target")
|
||||
|
||||
if __name__=="__main__":
|
||||
# Parse arguments
|
||||
i = 1
|
||||
nextarg = None
|
||||
configpath = 'project.cfg'
|
||||
actions = []
|
||||
target = ''
|
||||
while i<len(sys.argv):
|
||||
if nextarg is not None:
|
||||
if nextarg=='config':
|
||||
configpath = sys.argv[i]
|
||||
nextarg = None
|
||||
else:
|
||||
actions.append((nextarg, sys.argv[i]))
|
||||
nextarg = None
|
||||
elif sys.argv[i]=='-h':
|
||||
print_help()
|
||||
@ -101,7 +110,7 @@ if __name__=="__main__":
|
||||
elif sys.argv[i]=='-c':
|
||||
nextarg = 'config'
|
||||
else:
|
||||
nextarg = sys.argv[i]
|
||||
target = sys.argv[i]
|
||||
i += 1
|
||||
if nextarg is not None:
|
||||
print("ERROR: expected more arguments")
|
||||
@ -140,39 +149,29 @@ if __name__=="__main__":
|
||||
subprocesses = []
|
||||
|
||||
try:
|
||||
for action in actions:
|
||||
target = action[1]
|
||||
action = action[0]
|
||||
|
||||
if not config.has_section(f'build:{target}'):
|
||||
print("ERROR: config file has no build section for target")
|
||||
exit(1)
|
||||
devtarget = f'target:{config.get(f"build:{target}", "target", fallback="")}'
|
||||
if not config.has_section(devtarget):
|
||||
print("ERROR: config file has no section for device target")
|
||||
exit(1)
|
||||
toolchain = config.get(devtarget, 'toolchain', fallback="NONE")
|
||||
if toolchain=="NONE":
|
||||
print("ERROR: no toolchain specified for device target")
|
||||
toolchain = config.get(f'target.{target}', 'toolchain', fallback='NONE')
|
||||
if toolchain=='NONE':
|
||||
print("ERROR: No toolchain specified for target")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
exec(f"from remotesyn.{toolchain}.{action} import do, needed_files, generated_files")
|
||||
exec(f"from remotesyn.toolchains.{toolchain} import do")
|
||||
except ImportError:
|
||||
print(f"ERROR: Unknown action '{action}' for toolchain '{toolchain}'")
|
||||
print(f"ERROR: Unknown toolchain '{toolchain}'")
|
||||
exit(1)
|
||||
|
||||
# Send needed files
|
||||
for f in needed_files(config, target):
|
||||
# Send all files
|
||||
for it in config.items(f"target.{target}"):
|
||||
if it[0].startswith('files_'):
|
||||
for f in it[1].split():
|
||||
send_file(channel, f)
|
||||
|
||||
# ret = do(config, target, print, subprocesses)
|
||||
cmd(b'do'+sstr(f"{action} {target}"), channel)
|
||||
cmd(b'do'+sstr(target), channel)
|
||||
ret = 0
|
||||
|
||||
# Get generated files
|
||||
for f in generated_files(config, target):
|
||||
recv_file(channel, f)
|
||||
# Receive output dir
|
||||
recv_dir(channel, config.get('project', 'out_dir', fallback='out'))
|
||||
|
||||
if ret!=0:
|
||||
exit(ret)
|
||||
|
Reference in New Issue
Block a user