diff --git a/artiq/coredevice/analyzer.py b/artiq/coredevice/analyzer.py index 61ebe9036..c69a77183 100644 --- a/artiq/coredevice/analyzer.py +++ b/artiq/coredevice/analyzer.py @@ -57,10 +57,14 @@ def decode_message(data): ExceptionType(exception_type)) +DecodedDump = namedtuple( + "DecodedDump", "log_channel dds_channel dds_onehot_sel messages") + + def decode_dump(data): parts = struct.unpack(">IQbbbb", data[:16]) (sent_bytes, total_byte_count, - overflow_occured, log_channel, dds_channel, _) = parts + overflow_occured, log_channel, dds_channel, dds_onehot_sel) = parts if sent_bytes + 16 != len(data): raise ValueError("analyzer dump has incorrect length") @@ -76,7 +80,9 @@ def decode_dump(data): for _ in range(sent_bytes//32): messages.append(decode_message(data[position:position+32])) position += 32 - return messages, log_channel, dds_channel + return DecodedDump(log_channel, + dds_channel, bool(dds_onehot_sel), + messages) def vcd_codes(): @@ -255,7 +261,8 @@ def get_timescale(devices): return timescale -def create_channel_handlers(vcd_manager, devices, log_channel, dds_channel): +def create_channel_handlers(vcd_manager, devices, log_channel, + dds_channel, dds_onehot_sel): channel_handlers = dict() for name, desc in sorted(devices.items(), key=itemgetter(0)): if isinstance(desc, dict) and desc["type"] == "local": @@ -274,10 +281,8 @@ def create_channel_handlers(vcd_manager, devices, log_channel, dds_channel): if dds_handler.sysclk != sysclk: raise ValueError("All DDS channels must have the same sysclk") else: - # Assume AD9914 systems use one-hot selection signals - # TODO: move one-hot flag declarations into a single place dds_handler = DDSHandler(vcd_manager, desc["class"], - desc["class"] == "AD9914", sysclk) + dds_onehot_sel, sysclk) channel_handlers[dds_channel] = dds_handler dds_handler.add_dds_channel(name, dds_channel_ddsbus) return channel_handlers @@ -287,7 +292,7 @@ def get_message_time(message): return getattr(message, "timestamp", message.rtio_counter) -def messages_to_vcd(filename, devices, messages, log_channel, dds_channel): +def decoded_dump_to_vcd(filename, devices, dump): vcd_manager = VCDManager(filename) try: timescale = get_timescale(devices) @@ -296,11 +301,12 @@ def messages_to_vcd(filename, devices, messages, log_channel, dds_channel): else: logger.warning("unable to determine VCD timescale") - channel_handlers = create_channel_handlers(vcd_manager, devices, - log_channel, dds_channel) + channel_handlers = create_channel_handlers( + vcd_manager, devices, + dump.log_channel, dump.dds_channel, dump.dds_onehot_sel) vcd_manager.set_time(0) - messages = sorted(messages, key=get_message_time) + messages = sorted(dump.messages, key=get_message_time) if messages: start_time = get_message_time(messages[0]) for message in messages: diff --git a/artiq/frontend/artiq_coretool.py b/artiq/frontend/artiq_coretool.py index e5afb7fdf..79f402f9d 100755 --- a/artiq/frontend/artiq_coretool.py +++ b/artiq/frontend/artiq_coretool.py @@ -6,7 +6,7 @@ import struct from artiq.tools import verbosity_args, init_logger from artiq.master.databases import DeviceDB from artiq.master.worker_db import DeviceManager -from artiq.coredevice.analyzer import decode_dump, messages_to_vcd +from artiq.coredevice.analyzer import decode_dump, decoded_dump_to_vcd def get_argparser(): @@ -88,16 +88,15 @@ def main(): elif args.action == "cfg-erase": comm.flash_storage_erase() elif args.action == "analyzer-dump": - messages, log_channel, dds_channel = \ - decode_dump(comm.get_analyzer_dump()) + decoded_dump = decode_dump(comm.get_analyzer_dump()) if args.m: - print("Log channel:", log_channel) - print("DDS channel:", dds_channel) - for message in messages: + print("Log channel:", decoded_dump.log_channel) + print("DDS channel:", decoded_dump.dds_channel) + print("DDS one-hot:", decoded_dump.dds_onehot_sel) + for message in decoded_dump.messages: print(message) if args.f: - messages_to_vcd(args.f, device_mgr.get_device_db(), messages, - log_channel, dds_channel) + decoded_dump_to_vcd(args.f, device_mgr.get_device_db(), decoded_dump) finally: device_mgr.close_devices() diff --git a/artiq/runtime/analyzer.c b/artiq/runtime/analyzer.c index 9a3440edb..4a3ec9de2 100644 --- a/artiq/runtime/analyzer.c +++ b/artiq/runtime/analyzer.c @@ -13,7 +13,7 @@ struct analyzer_header { unsigned char overflow_occured; unsigned char log_channel; unsigned char dds_channel; - unsigned char padding; + unsigned char dds_onehot_sel; } __attribute__((packed)); @@ -73,7 +73,11 @@ void analyzer_start(void) analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read(); analyzer_header.log_channel = 0; analyzer_header.dds_channel = CONFIG_RTIO_DDS_CHANNEL; - analyzer_header.padding = 0; +#ifdef DDS_ONEHOT_SEL + analyzer_header.dds_onehot_sel = 1; +#else + analyzer_header.dds_onehot_sel = 0; +#endif offset_consumed = 0; offset_sent = 0;