litescope_gui: Add initial and very simple GUI support.
This commit is contained in:
parent
1d85cbcb6d
commit
f1acdf4c17
|
@ -11,6 +11,8 @@ import os
|
||||||
import re
|
import re
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from litex import RemoteClient
|
from litex import RemoteClient
|
||||||
|
@ -23,7 +25,7 @@ def get_signals(csvname, group):
|
||||||
with open(csvname) as f:
|
with open(csvname) as f:
|
||||||
reader = csv.reader(f, delimiter=",", quotechar="#")
|
reader = csv.reader(f, delimiter=",", quotechar="#")
|
||||||
for t, g, n, v in reader:
|
for t, g, n, v in reader:
|
||||||
if t == "signal" and g == group:
|
if t == "signal" and g == str(group):
|
||||||
signals.append(n)
|
signals.append(n)
|
||||||
return signals
|
return signals
|
||||||
|
|
||||||
|
@ -74,41 +76,119 @@ def add_triggers(args, analyzer, signals):
|
||||||
added = True
|
added = True
|
||||||
return added
|
return added
|
||||||
|
|
||||||
|
# Run Batch/GUI -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def run_batch(args):
|
||||||
|
bus = RemoteClient(csr_csv=args.csr_csv)
|
||||||
|
bus.open()
|
||||||
|
|
||||||
|
basename = os.path.splitext(os.path.basename(args.csv))[0]
|
||||||
|
signals = get_signals(args.csv, args.group)
|
||||||
|
|
||||||
|
# Configure and run LiteScope analyzer.
|
||||||
|
analyzer = LiteScopeAnalyzerDriver(bus.regs, basename, debug=True)
|
||||||
|
analyzer.configure_group(args.group)
|
||||||
|
analyzer.configure_subsampler(args.subsampling)
|
||||||
|
if not add_triggers(args, analyzer, signals):
|
||||||
|
print("No trigger, immediate capture.")
|
||||||
|
analyzer.run(
|
||||||
|
offset = int(args.offset, 0),
|
||||||
|
length = None if args.length is None else int(args.length, 0)
|
||||||
|
)
|
||||||
|
analyzer.wait_done()
|
||||||
|
analyzer.upload()
|
||||||
|
analyzer.save(args.dump)
|
||||||
|
|
||||||
|
# Close remove control.
|
||||||
|
bus.close()
|
||||||
|
|
||||||
|
def run_gui(args):
|
||||||
|
import dearpygui.dearpygui as dpg
|
||||||
|
|
||||||
|
bus = RemoteClient(csr_csv=args.csr_csv)
|
||||||
|
bus.open()
|
||||||
|
|
||||||
|
triggers = get_signals(args.csv, args.group)
|
||||||
|
|
||||||
|
def capture_callback():
|
||||||
|
basename = os.path.splitext(os.path.basename(args.csv))[0]
|
||||||
|
analyzer = LiteScopeAnalyzerDriver(bus.regs, basename, debug=True)
|
||||||
|
analyzer.configure_group(int(dpg.get_value(item="capture_group"), 0))
|
||||||
|
analyzer.configure_subsampler(int(dpg.get_value(item="capture_subsampling"), 0))
|
||||||
|
trigger_cond = {}
|
||||||
|
for trigger in triggers:
|
||||||
|
trigger_cond[trigger] = dpg.get_value(trigger)
|
||||||
|
analyzer.add_trigger(cond=trigger_cond)
|
||||||
|
analyzer.run(
|
||||||
|
offset = int(dpg.get_value(item="capture_offset"), 0),
|
||||||
|
length = int(dpg.get_value(item="capture_length"), 0),
|
||||||
|
)
|
||||||
|
dpg.set_value("capture_status", "Running...")
|
||||||
|
analyzer.wait_done()
|
||||||
|
dpg.set_value("capture_status", "Uploading...")
|
||||||
|
analyzer.upload()
|
||||||
|
dpg.set_value("capture_status", "Writing...")
|
||||||
|
analyzer.save(dpg.get_value(item="capture_dump"))
|
||||||
|
dpg.set_value("capture_status", "Idle")
|
||||||
|
|
||||||
|
dpg.create_context()
|
||||||
|
dpg.create_viewport(title="LiteScope CLI GUI", max_width=400, always_on_top=True)
|
||||||
|
dpg.setup_dearpygui()
|
||||||
|
|
||||||
|
with dpg.window(label="Capture", autosize=True):
|
||||||
|
dpg.add_text("Parameters")
|
||||||
|
dpg.add_input_text(indent=8, label="Offset", tag="capture_offset", default_value=args.offset)
|
||||||
|
dpg.add_input_text(indent=8, label="Length", tag="capture_length", default_value="128") # FIXME
|
||||||
|
dpg.add_input_text(indent=8, label="Group", tag="capture_group", default_value="0") # FIXME
|
||||||
|
dpg.add_input_text(indent=8, label="Subsampling", tag="capture_subsampling", default_value="1") # FIXME
|
||||||
|
dpg.add_input_text(indent=8, label="Dump", tag="capture_dump", default_value=args.dump)
|
||||||
|
dpg.add_text("Control/Status")
|
||||||
|
with dpg.group(horizontal=True):
|
||||||
|
dpg.add_button(label="Run", callback=capture_callback)
|
||||||
|
dpg.add_text(tag="capture_status", default_value="Idle")
|
||||||
|
|
||||||
|
with dpg.window(label="Triggers", autosize=True, pos=(0, 250)):
|
||||||
|
for trigger in triggers:
|
||||||
|
dpg.add_input_text(indent=8, label=trigger, tag=trigger, default_value="0bx", width=100)
|
||||||
|
|
||||||
|
dpg.show_viewport()
|
||||||
|
dpg.start_dearpygui()
|
||||||
|
dpg.destroy_context()
|
||||||
|
|
||||||
|
bus.close()
|
||||||
|
|
||||||
# Main ---------------------------------------------------------------------------------------------
|
# Main ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(description="""LiteScope Client utility""")
|
parser = argparse.ArgumentParser(description="""LiteScope Client utility""")
|
||||||
parser.add_argument("-r", "--rising-edge", action="append", help="Add rising edge trigger")
|
parser.add_argument("-r", "--rising-edge", action="append", help="Add rising edge trigger.")
|
||||||
parser.add_argument("-f", "--falling-edge", action="append", help="Add falling edge trigger")
|
parser.add_argument("-f", "--falling-edge", action="append", help="Add falling edge trigger.")
|
||||||
parser.add_argument("-v", "--value-trigger", action="append", nargs=2, help="Add conditional trigger with given value",
|
parser.add_argument("-v", "--value-trigger", action="append", nargs=2, help="Add conditional trigger with given value.",
|
||||||
metavar=("TRIGGER", "VALUE"))
|
metavar=("TRIGGER", "VALUE"))
|
||||||
parser.add_argument("-l", "--list", action="store_true", help="List signal choices")
|
parser.add_argument("-l", "--list", action="store_true", help="List signal choices.")
|
||||||
parser.add_argument("--csv", default="analyzer.csv", help="Analyzer CSV file")
|
parser.add_argument("--csv", default="analyzer.csv", help="Analyzer CSV file.")
|
||||||
parser.add_argument("--csr-csv", default="csr.csv", help="SoC CSV file")
|
parser.add_argument("--csr-csv", default="csr.csv", help="SoC CSV file.")
|
||||||
parser.add_argument("--group", default="0", help="Capture Group")
|
parser.add_argument("--group", default=0, type=int, help="Capture Group.")
|
||||||
parser.add_argument("--subsampling", default="1", help="Capture Subsampling")
|
parser.add_argument("--subsampling", default=1, type=int, help="Capture Subsampling.")
|
||||||
parser.add_argument("--offset", default="32", help="Capture Offset")
|
parser.add_argument("--offset", default="32", help="Capture Offset.")
|
||||||
parser.add_argument("--length", default=None, help="Capture Length")
|
parser.add_argument("--length", default=None, help="Capture Length.")
|
||||||
parser.add_argument("--dump", default="dump.vcd", help="Capture Filename")
|
parser.add_argument("--dump", default="dump.vcd", help="Capture Filename.")
|
||||||
|
parser.add_argument("--gui", action="store_true", help="Run Gui.")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|
||||||
basename = os.path.splitext(os.path.basename(args.csv))[0]
|
|
||||||
|
|
||||||
# Check if analyzer file is present and exit if not.
|
# Check if analyzer file is present and exit if not.
|
||||||
if not os.path.exists(args.csv):
|
if not os.path.exists(args.csv):
|
||||||
raise ValueError("{} not found. This is necessary to load the wires which have been tapped to scope."
|
raise ValueError("{} not found. This is necessary to load the wires which have been tapped to scope."
|
||||||
"Try setting --csv to value of the csr_csv argument to LiteScopeAnalyzer in the SoC.".format(args.csv))
|
"Try setting --csv to value of the csr_csv argument to LiteScopeAnalyzer in the SoC.".format(args.csv))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Get list of signals from analyzer configuratio file.
|
|
||||||
signals = get_signals(args.csv, args.group)
|
|
||||||
|
|
||||||
# If in list mode, list signals and exit.
|
# If in list mode, list signals and exit.
|
||||||
if args.list:
|
if args.list:
|
||||||
|
signals = get_signals(args.csv, args.group)
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
print(signal)
|
print(signal)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -117,27 +197,13 @@ def main():
|
||||||
if not os.path.exists(args.csr_csv):
|
if not os.path.exists(args.csr_csv):
|
||||||
raise ValueError("{} not found. This is necessary to load the 'regs' of the remote. Try setting --csr-csv here to "
|
raise ValueError("{} not found. This is necessary to load the 'regs' of the remote. Try setting --csr-csv here to "
|
||||||
"the path to the --csr-csv argument of the SoC build.".format(args.csr_csv))
|
"the path to the --csr-csv argument of the SoC build.".format(args.csr_csv))
|
||||||
bus = RemoteClient(csr_csv=args.csr_csv)
|
|
||||||
bus.open()
|
|
||||||
|
|
||||||
# Configure and run LiteScope analyzer.
|
# Run Batch/Gui.
|
||||||
try:
|
if args.gui:
|
||||||
analyzer = LiteScopeAnalyzerDriver(bus.regs, basename, debug=True)
|
run_gui(args)
|
||||||
analyzer.configure_group(int(args.group, 0))
|
else:
|
||||||
analyzer.configure_subsampler(int(args.subsampling, 0))
|
run_batch(args)
|
||||||
if not add_triggers(args, analyzer, signals):
|
|
||||||
print("No trigger, immediate capture.")
|
|
||||||
analyzer.run(
|
|
||||||
offset = int(args.offset, 0),
|
|
||||||
length = None if args.length is None else int(args.length, 0)
|
|
||||||
)
|
|
||||||
analyzer.wait_done()
|
|
||||||
analyzer.upload()
|
|
||||||
analyzer.save(args.dump)
|
|
||||||
|
|
||||||
# Close remove control.
|
|
||||||
finally:
|
|
||||||
bus.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue