remove legacy code, now feature complete with new scripts
This commit is contained in:
parent
030a841f53
commit
566a3624d8
5
build.py
5
build.py
|
|
@ -1,5 +0,0 @@
|
|||
import os
|
||||
|
||||
os.system('echo "#!/usr/bin/python3" > manta')
|
||||
os.system("cat manta.py >> manta")
|
||||
os.system("chmod +x manta")
|
||||
|
|
@ -26,21 +26,21 @@ outfile = f"{of}/out.bit"
|
|||
logfile = f"{of}/build.log"
|
||||
|
||||
synthrpt = [
|
||||
"report_timing",
|
||||
"report_timing_summary",
|
||||
"report_utilization",
|
||||
]
|
||||
"report_timing",
|
||||
"report_timing_summary",
|
||||
"report_utilization",
|
||||
]
|
||||
|
||||
placerpt = synthrpt.copy()
|
||||
placerpt.extend(['report_clock_utilization'])
|
||||
placerpt.extend(["report_clock_utilization"])
|
||||
|
||||
routerpt = [
|
||||
'report_drc',
|
||||
'report_power',
|
||||
'report_route_status',
|
||||
'report_timing',
|
||||
'report_timing_summary',
|
||||
]
|
||||
"report_drc",
|
||||
"report_power",
|
||||
"report_route_status",
|
||||
"report_timing",
|
||||
"report_timing_summary",
|
||||
]
|
||||
|
||||
usagestr = f"""
|
||||
{progname}: build SystemVerilog code remotely for 2022 6.205 labs
|
||||
|
|
@ -54,190 +54,248 @@ options:
|
|||
-o: set the output products directory (default is {of})
|
||||
"""
|
||||
|
||||
|
||||
def debuglog(s):
|
||||
if verbose: print(s)
|
||||
if verbose:
|
||||
print(s)
|
||||
|
||||
|
||||
def usage():
|
||||
print(usagestr)
|
||||
sys.exit(1)
|
||||
print(usagestr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def getargs():
|
||||
global diagnostics
|
||||
global quiet
|
||||
global machine
|
||||
global logfile
|
||||
global outfile
|
||||
global projectdir
|
||||
global of
|
||||
global verbose
|
||||
global diagnostics
|
||||
global quiet
|
||||
global machine
|
||||
global logfile
|
||||
global outfile
|
||||
global projectdir
|
||||
global of
|
||||
global verbose
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "dm:o:p:qv")
|
||||
except getopt.GetoptError as err:
|
||||
print(err)
|
||||
usage()
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "dm:o:p:qv")
|
||||
except getopt.GetoptError as err:
|
||||
print(err)
|
||||
usage()
|
||||
|
||||
if args: usage()
|
||||
for o, v in opts:
|
||||
if o == '-d': diagnostics = True
|
||||
elif o == '-q': quiet = True
|
||||
elif o == '-m': machine = v
|
||||
elif o == '-p': projectdir = v
|
||||
elif o == '-o': of = v
|
||||
elif o == '-v': verbose = True
|
||||
else:
|
||||
print(f"unrecognized option {o}")
|
||||
usage()
|
||||
if args:
|
||||
usage()
|
||||
for o, v in opts:
|
||||
if o == "-d":
|
||||
diagnostics = True
|
||||
elif o == "-q":
|
||||
quiet = True
|
||||
elif o == "-m":
|
||||
machine = v
|
||||
elif o == "-p":
|
||||
projectdir = v
|
||||
elif o == "-o":
|
||||
of = v
|
||||
elif o == "-v":
|
||||
verbose = True
|
||||
else:
|
||||
print(f"unrecognized option {o}")
|
||||
usage()
|
||||
|
||||
outfile = f"{of}/out.bit"
|
||||
logfile = f"{of}/build.log"
|
||||
|
||||
outfile = f"{of}/out.bit"
|
||||
logfile = f"{of}/build.log"
|
||||
|
||||
def make_posix(path):
|
||||
return str(pathlib.Path(path).as_posix())
|
||||
return str(pathlib.Path(path).as_posix())
|
||||
|
||||
|
||||
def regfiles():
|
||||
ftt = {}
|
||||
debuglog(f"projectdir is {projectdir}")
|
||||
for dirpath, subdirs, files in os.walk(projectdir):
|
||||
if 'src' not in dirpath and 'xdc' not in dirpath and 'data' not in dirpath and 'ip' not in dirpath:
|
||||
continue
|
||||
if dirpath.startswith("./"): dirpath = dirpath[2:]
|
||||
for file in files:
|
||||
fpath = os.path.join(dirpath, file)
|
||||
debuglog(f"considering {fpath}")
|
||||
fpath = make_posix(fpath)
|
||||
ftt = {}
|
||||
debuglog(f"projectdir is {projectdir}")
|
||||
for dirpath, subdirs, files in os.walk(projectdir):
|
||||
if (
|
||||
"src" not in dirpath
|
||||
and "xdc" not in dirpath
|
||||
and "data" not in dirpath
|
||||
and "ip" not in dirpath
|
||||
):
|
||||
continue
|
||||
if dirpath.startswith("./"):
|
||||
dirpath = dirpath[2:]
|
||||
for file in files:
|
||||
fpath = os.path.join(dirpath, file)
|
||||
debuglog(f"considering {fpath}")
|
||||
fpath = make_posix(fpath)
|
||||
|
||||
if file.lower().endswith('.v'): ftt[fpath] = 'source'
|
||||
elif file.lower().endswith('.sv'): ftt[fpath] = 'source'
|
||||
elif file.lower().endswith('.vh'): ftt[fpath] = 'source'
|
||||
elif file.lower().endswith('.svh'): ftt[fpath] = 'source'
|
||||
elif file.lower().endswith('.xdc'): ftt[fpath] = 'xdc'
|
||||
elif file.lower().endswith('.mem'): ftt[fpath] = 'mem'
|
||||
elif file.lower().endswith('.xci'): ftt[fpath] = 'ip'
|
||||
elif file.lower().endswith('.prj'): ftt[fpath] = 'mig'
|
||||
if file.lower().endswith(".v"):
|
||||
ftt[fpath] = "source"
|
||||
elif file.lower().endswith(".sv"):
|
||||
ftt[fpath] = "source"
|
||||
elif file.lower().endswith(".vh"):
|
||||
ftt[fpath] = "source"
|
||||
elif file.lower().endswith(".svh"):
|
||||
ftt[fpath] = "source"
|
||||
elif file.lower().endswith(".xdc"):
|
||||
ftt[fpath] = "xdc"
|
||||
elif file.lower().endswith(".mem"):
|
||||
ftt[fpath] = "mem"
|
||||
elif file.lower().endswith(".xci"):
|
||||
ftt[fpath] = "ip"
|
||||
elif file.lower().endswith(".prj"):
|
||||
ftt[fpath] = "mig"
|
||||
|
||||
debuglog(f"elaborated file list {ftt}")
|
||||
return ftt
|
||||
|
||||
debuglog(f"elaborated file list {ftt}")
|
||||
return ftt
|
||||
|
||||
# messages are newline delineated per lab-bs.1
|
||||
# utilize this to cheat a little bit
|
||||
def spqsend(p, msg):
|
||||
debuglog(f"writing {len(msg)} bytes over the wire")
|
||||
debuglog(f"full message: {msg}")
|
||||
p.stdin.write(msg + b'\n')
|
||||
p.stdin.flush()
|
||||
debuglog(f"writing {len(msg)} bytes over the wire")
|
||||
debuglog(f"full message: {msg}")
|
||||
p.stdin.write(msg + b"\n")
|
||||
p.stdin.flush()
|
||||
|
||||
|
||||
def spsend(p, msg):
|
||||
debuglog(f"running {msg}")
|
||||
p.stdin.write((msg + '\n').encode())
|
||||
p.stdin.flush()
|
||||
debuglog(f"running {msg}")
|
||||
p.stdin.write((msg + "\n").encode())
|
||||
p.stdin.flush()
|
||||
|
||||
|
||||
def sprecv(p):
|
||||
l = p.stdout.readline().decode()
|
||||
debuglog(f"got {l}")
|
||||
return l
|
||||
l = p.stdout.readline().decode()
|
||||
debuglog(f"got {l}")
|
||||
return l
|
||||
|
||||
|
||||
def xsprecv(p):
|
||||
l = sprecv(p)
|
||||
if (l.startswith("ERR")):
|
||||
print("received unexpected server error!")
|
||||
print(l)
|
||||
sys.exit(1)
|
||||
return l
|
||||
l = sprecv(p)
|
||||
if l.startswith("ERR"):
|
||||
print("received unexpected server error!")
|
||||
print(l)
|
||||
sys.exit(1)
|
||||
return l
|
||||
|
||||
|
||||
def spstart(xargv):
|
||||
debuglog(f"spawning {xargv}")
|
||||
p = subprocess.PIPE
|
||||
return subprocess.Popen(xargv, stdin=p, stdout=p, stderr=p)
|
||||
debuglog(f"spawning {xargv}")
|
||||
p = subprocess.PIPE
|
||||
return subprocess.Popen(xargv, stdin=p, stdout=p, stderr=p)
|
||||
|
||||
|
||||
def copyfiles(p, ftt):
|
||||
for f, t in ftt.items():
|
||||
fsize = os.path.getsize(f)
|
||||
with open(f, 'rb') as fd:
|
||||
spsend(p, f"write {f} {fsize}")
|
||||
time.sleep(0.1) #?
|
||||
spqsend(p, fd.read())
|
||||
xsprecv(p)
|
||||
for f, t in ftt.items():
|
||||
fsize = os.path.getsize(f)
|
||||
with open(f, "rb") as fd:
|
||||
spsend(p, f"write {f} {fsize}")
|
||||
time.sleep(0.1) # ?
|
||||
spqsend(p, fd.read())
|
||||
xsprecv(p)
|
||||
|
||||
spsend(p, f"type {f} {t}")
|
||||
xsprecv(p)
|
||||
|
||||
spsend(p, f"type {f} {t}")
|
||||
xsprecv(p)
|
||||
|
||||
# size message returns ... %zu bytes
|
||||
def readfile(p, file, targetfile):
|
||||
spsend(p, f"size {file}")
|
||||
size = int(xsprecv(p).split()[-2])
|
||||
spsend(p, f"read {file}")
|
||||
spsend(p, f"size {file}")
|
||||
size = int(xsprecv(p).split()[-2])
|
||||
spsend(p, f"read {file}")
|
||||
|
||||
with open(targetfile, "wb+") as fd:
|
||||
fd.write(p.stdout.read(size))
|
||||
|
||||
xsprecv(p)
|
||||
|
||||
with open(targetfile, 'wb+') as fd:
|
||||
fd.write(p.stdout.read(size))
|
||||
|
||||
xsprecv(p)
|
||||
|
||||
def build(p):
|
||||
cmd = "build"
|
||||
if diagnostics: cmd += " -d"
|
||||
if quiet: cmd += " -q"
|
||||
cmd += f" obj"
|
||||
cmd = "build"
|
||||
if diagnostics:
|
||||
cmd += " -d"
|
||||
if quiet:
|
||||
cmd += " -q"
|
||||
cmd += f" obj"
|
||||
|
||||
print(f"Output target will be {outfile}")
|
||||
print(f"Output target will be {outfile}")
|
||||
|
||||
spsend(p, cmd)
|
||||
print("Building your code ... (this may take a while, be patient)")
|
||||
result = sprecv(p)
|
||||
spsend(p, cmd)
|
||||
print("Building your code ... (this may take a while, be patient)")
|
||||
result = sprecv(p)
|
||||
|
||||
if result.startswith("ERR"): print("Something went wrong!")
|
||||
else:
|
||||
readfile(p, "obj/out.bit", outfile)
|
||||
print(f"Build succeeded, output at {outfile}")
|
||||
|
||||
readfile(p, "obj/build.log", logfile)
|
||||
print(f"Log file available at {logfile}")
|
||||
if result.startswith("ERR"):
|
||||
print("Something went wrong!")
|
||||
else:
|
||||
readfile(p, "obj/out.bit", outfile)
|
||||
print(f"Build succeeded, output at {outfile}")
|
||||
|
||||
readfile(p, "obj/build.log", logfile)
|
||||
print(f"Log file available at {logfile}")
|
||||
|
||||
if diagnostics:
|
||||
for rpt in synthrpt:
|
||||
readfile(p, f"obj/synthrpt_{rpt}.rpt", f"{of}/synthrpt_{rpt}.rpt")
|
||||
for rpt in placerpt:
|
||||
readfile(p, f"obj/placerpt_{rpt}.rpt", f"{of}/placerpt_{rpt}.rpt")
|
||||
for rpt in routerpt:
|
||||
readfile(p, f"obj/routerpt_{rpt}.rpt", f"{of}/routerpt_{rpt}.rpt")
|
||||
print(f"Diagnostics available in {of}")
|
||||
|
||||
if (diagnostics):
|
||||
for rpt in synthrpt:
|
||||
readfile(p, f"obj/synthrpt_{rpt}.rpt", f"{of}/synthrpt_{rpt}.rpt")
|
||||
for rpt in placerpt:
|
||||
readfile(p, f"obj/placerpt_{rpt}.rpt", f"{of}/placerpt_{rpt}.rpt")
|
||||
for rpt in routerpt:
|
||||
readfile(p, f"obj/routerpt_{rpt}.rpt", f"{of}/routerpt_{rpt}.rpt")
|
||||
print(f"Diagnostics available in {of}")
|
||||
|
||||
def main():
|
||||
global p
|
||||
getargs()
|
||||
ftt = regfiles()
|
||||
global p
|
||||
getargs()
|
||||
ftt = regfiles()
|
||||
|
||||
if not os.path.isdir(of):
|
||||
print(f"output path {of} does not exist! create it or use -o?")
|
||||
usage()
|
||||
|
||||
if platform.system() == 'Darwin' or platform.system() == 'Linux':
|
||||
xargv = ['ssh', '-p', f"{port}", '-o', "StrictHostKeyChecking=no", '-o', 'UserKnownHostsFile=/dev/null']
|
||||
if not os.path.isdir(of):
|
||||
print(f"output path {of} does not exist! create it or use -o?")
|
||||
usage()
|
||||
|
||||
elif platform.system() == 'Windows':
|
||||
xargv = ['ssh', '-p', f"{port}", '-o', "StrictHostKeyChecking=no", '-o', 'UserKnownHostsFile=nul']
|
||||
if platform.system() == "Darwin" or platform.system() == "Linux":
|
||||
xargv = [
|
||||
"ssh",
|
||||
"-p",
|
||||
f"{port}",
|
||||
"-o",
|
||||
"StrictHostKeyChecking=no",
|
||||
"-o",
|
||||
"UserKnownHostsFile=/dev/null",
|
||||
]
|
||||
|
||||
else:
|
||||
raise RuntimeError('Your OS is not recognized, unsure of how to format SSH command.')
|
||||
|
||||
|
||||
xargv.append(f"{user}@{machine}")
|
||||
p = spstart(xargv)
|
||||
elif platform.system() == "Windows":
|
||||
xargv = [
|
||||
"ssh",
|
||||
"-p",
|
||||
f"{port}",
|
||||
"-o",
|
||||
"StrictHostKeyChecking=no",
|
||||
"-o",
|
||||
"UserKnownHostsFile=nul",
|
||||
]
|
||||
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"Your OS is not recognized, unsure of how to format SSH command."
|
||||
)
|
||||
|
||||
xargv.append(f"{user}@{machine}")
|
||||
p = spstart(xargv)
|
||||
|
||||
spsend(p, "help")
|
||||
result = xsprecv(p)
|
||||
debuglog(result)
|
||||
|
||||
copyfiles(p, ftt)
|
||||
build(p)
|
||||
spsend(p, "exit")
|
||||
p.wait()
|
||||
|
||||
spsend(p, "help")
|
||||
result = xsprecv(p)
|
||||
debuglog(result)
|
||||
|
||||
copyfiles(p, ftt)
|
||||
build(p)
|
||||
spsend(p, "exit")
|
||||
p.wait()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try: main()
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
if p:
|
||||
debuglog("killing ssh")
|
||||
os.kill(p.pid, signal.SIGINT)
|
||||
p.wait()
|
||||
raise e
|
||||
try:
|
||||
main()
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
if p:
|
||||
debuglog("killing ssh")
|
||||
os.kill(p.pid, signal.SIGINT)
|
||||
p.wait()
|
||||
raise e
|
||||
|
|
|
|||
71
gen_ila.py
71
gen_ila.py
|
|
@ -1,71 +0,0 @@
|
|||
import json
|
||||
import yaml
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
# this works by taking a template file, parsing it for hooks, and then dropping in our spicy bits of verilog in those hooks.
|
||||
# might update this later to just properly instantiate an ILA for us and we do this with parameters, but
|
||||
# the fundamental thing i care about is that systemverilog does not live in this file.
|
||||
|
||||
fpath = 'ila.json' # will update for argv soon!
|
||||
|
||||
with open(fpath, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# make sure file is okay
|
||||
assert config["probes"]
|
||||
assert config["triggers"]
|
||||
assert config["uart"] or config["ethernet"] # <- i have ideas hehe
|
||||
|
||||
def splice(source, find, replace):
|
||||
# find all instances of find in the source, and replace with replace
|
||||
#assert source.count(find) == 1
|
||||
return source.replace(find, replace)
|
||||
|
||||
|
||||
with open('src/ila_template.sv', 'r') as t:
|
||||
ila_template = t.read()
|
||||
|
||||
# add timestamp and user
|
||||
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
ila_template = splice(ila_template, '@TIMESTAMP', timestamp);
|
||||
|
||||
user = os.environ.get('USER', os.environ.get('USERNAME'))
|
||||
ila_template = splice(ila_template, '@USER', user);
|
||||
|
||||
# add trigger
|
||||
trigger = [f'({trigger})' for trigger in config['triggers']]
|
||||
trigger = ' || '.join(trigger)
|
||||
ila_template = splice(ila_template, '@TRIGGER', trigger);
|
||||
|
||||
# add concat
|
||||
concat = [name for name in config['probes']]
|
||||
concat = ', '.join(concat)
|
||||
concat = '{' + concat + '};'
|
||||
ila_template = splice(ila_template, '@CONCAT', concat);
|
||||
|
||||
# add probes to ila module definition
|
||||
probe_verilog = []
|
||||
for name, width in config['probes'].items():
|
||||
if width == 1:
|
||||
probe_verilog.append(f'input wire {name},')
|
||||
|
||||
else:
|
||||
probe_verilog.append(f'input wire [{width-1}:0] {name},')
|
||||
|
||||
probe_verilog = '\n\t'.join(probe_verilog)
|
||||
ila_template = splice(ila_template, '@PROBES', probe_verilog);
|
||||
|
||||
# add sample width and depth
|
||||
sample_width = sum([width for name, width in config['probes'].items()])
|
||||
ila_template = splice(ila_template, '@SAMPLE_WIDTH', str(sample_width))
|
||||
ila_template = splice(ila_template, '@SAMPLE_DEPTH', str(config['sample_depth']));
|
||||
|
||||
# add UART configuration
|
||||
ila_template = splice(ila_template, '@DATA_WIDTH', str(int(config['uart']['data'])));
|
||||
ila_template = splice(ila_template, '@BAUDRATE', str(config['uart']['baudrate']));
|
||||
ila_template = splice(ila_template, '@CLK_FREQ_HZ', str(int(config['clock_freq'])));
|
||||
|
||||
# write output file
|
||||
with open('src/ila.sv', 'w') as i:
|
||||
i.write(ila_template)
|
||||
4
manta.py
4
manta.py
|
|
@ -278,7 +278,7 @@ def make_widths(config):
|
|||
# [12, 1, 3] should produce
|
||||
# [ (11,0) , (12, 12), (15,13) ]
|
||||
|
||||
widths = list(config["probes"].values())
|
||||
widths = list(config["downlink"]["probes"].values())
|
||||
|
||||
parts = []
|
||||
for i, width in enumerate(widths):
|
||||
|
|
@ -306,7 +306,7 @@ def export_waveform(config, data, path):
|
|||
) as writer:
|
||||
# add probes to vcd file
|
||||
vcd_probes = []
|
||||
for name, width in config["probes"].items():
|
||||
for name, width in config["downlink"]["probes"].items():
|
||||
probe = writer.register_var("ila", name, "wire", size=width)
|
||||
vcd_probes.append(probe)
|
||||
|
||||
|
|
|
|||
159
run_ila.py
159
run_ila.py
|
|
@ -1,159 +0,0 @@
|
|||
from sys import argv
|
||||
import json
|
||||
import serial
|
||||
from vcd import VCDWriter
|
||||
from datetime import datetime
|
||||
|
||||
def check_config(config):
|
||||
"""Check that configuration is okay"""
|
||||
assert config["probes"]
|
||||
assert config["triggers"]
|
||||
assert config["uart"]
|
||||
|
||||
def setup_serial(ser, config):
|
||||
ser.baudrate = config['uart']['baudrate']
|
||||
ser.port = config['uart']['port']
|
||||
ser.timeout = config['uart']['timeout']
|
||||
|
||||
# setup number of data bits
|
||||
if config['uart']['data'] == 8:
|
||||
ser.bytesize = serial.EIGHTBITS
|
||||
|
||||
elif config['uart']['data'] == 7:
|
||||
ser.bytesize = serial.SEVENBITS
|
||||
|
||||
elif config['uart']['data'] == 6:
|
||||
ser.bytesize = serial.SIXBITS
|
||||
|
||||
elif config['uart']['data'] == 5:
|
||||
ser.bytesize = serial.FIVEBITS
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid number of data bits in UART configuration.")
|
||||
|
||||
# setup number of stop bits
|
||||
if config['uart']['stop'] == 1:
|
||||
ser.stopbits = serial.STOPBITS_ONE
|
||||
|
||||
elif config['uart']['stop'] == 1.5:
|
||||
ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE
|
||||
|
||||
elif config['uart']['stop'] == 2:
|
||||
ser.stopbits = serial.STOPBITS_TWO
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid number of stop bits in UART configuration.")
|
||||
|
||||
# setup parity
|
||||
if config['uart']['parity'] == 'none':
|
||||
ser.parity = serial.PARITY_NONE
|
||||
|
||||
elif config['uart']['parity'] == 'even':
|
||||
ser.parity = serial.PARITY_EVEN
|
||||
|
||||
elif config['uart']['parity'] == 'odd':
|
||||
ser.parity = serial.PARITY_ODD
|
||||
|
||||
elif config['uart']['parity'] == 'mark':
|
||||
ser.parity = serial.PARITY_MARK
|
||||
|
||||
elif config['uart']['parity'] == 'space':
|
||||
ser.parity = serial.PARITY_SPACE
|
||||
|
||||
else:
|
||||
raise ValueError("Invalid parity setting in UART configuration.")
|
||||
|
||||
def part_select(data, width):
|
||||
top, bottom = width
|
||||
|
||||
assert top >= bottom
|
||||
|
||||
mask = 2**(top - bottom + 1) - 1
|
||||
return (data >> bottom) & mask
|
||||
|
||||
def make_widths(config):
|
||||
# {probe0, probe1, probe2}
|
||||
# [12, 1, 3] should produce
|
||||
# [ (11,0) , (12, 12), (15,13) ]
|
||||
|
||||
widths = list(config['probes'].values())
|
||||
|
||||
parts = []
|
||||
for i, width in enumerate(widths):
|
||||
if (i == 0):
|
||||
parts.append( (width - 1, 0) )
|
||||
|
||||
else:
|
||||
parts.append( ((parts[i-1][1] + width) , (parts[i-1][1] + 1)) )
|
||||
|
||||
# reversing this list is a little bit of a hack, should fix/document
|
||||
return parts[::-1]
|
||||
|
||||
|
||||
## Main Program
|
||||
|
||||
# parse args
|
||||
if len(argv) == 1 or argv[1] == '-h':
|
||||
print("""
|
||||
run_ila.py: interface with the ILA on the FPGA, setting triggers and downlinking waveform data.
|
||||
usage: python3 run_ila.py [config input file] [vcd output file]
|
||||
options:
|
||||
-h: print this help menu
|
||||
-l: list all available serial devices
|
||||
|
||||
example: python3 run_ila.py ila.json ila.vcd
|
||||
""")
|
||||
exit()
|
||||
|
||||
elif argv[1] == '-l':
|
||||
import serial.tools.list_ports
|
||||
|
||||
for info in serial.tools.list_ports.comports():
|
||||
print(info)
|
||||
|
||||
elif len(argv) == 2:
|
||||
config_fpath = argv[1]
|
||||
vcd_fpath = 'ila.vcd'
|
||||
|
||||
|
||||
elif len(argv) == 3:
|
||||
config_fpath = argv[1]
|
||||
vcd_fpath = argv[2]
|
||||
|
||||
else:
|
||||
exit()
|
||||
|
||||
# read config
|
||||
with open(config_fpath, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# obtain bytestream from FPGA
|
||||
with serial.Serial() as ser:
|
||||
setup_serial(ser, config)
|
||||
ser.open()
|
||||
ser.flushInput()
|
||||
ser.write(b'\x30')
|
||||
data = ser.read(4096)
|
||||
|
||||
# export VCD
|
||||
vcd_file = open(vcd_fpath, 'w')
|
||||
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
|
||||
with VCDWriter(vcd_file, timescale='10 ns', date=timestamp, version = 'openILA') as writer:
|
||||
|
||||
# add probes to vcd file
|
||||
vcd_probes = []
|
||||
for name, width in config['probes'].items():
|
||||
probe = writer.register_var('ila', name, 'wire', size = width)
|
||||
vcd_probes.append(probe)
|
||||
|
||||
# calculate bit widths for part selecting
|
||||
widths = make_widths(config)
|
||||
|
||||
# slice data, and dump to vcd file
|
||||
for timestamp, value in enumerate(data):
|
||||
for probe_num, probe in enumerate(vcd_probes):
|
||||
val = part_select(value, widths[probe_num])
|
||||
writer.change(probe, timestamp, val)
|
||||
|
||||
vcd_file.close()
|
||||
Loading…
Reference in New Issue