coredevice/analyzer: set VCD timescale

This commit is contained in:
Sebastien Bourdeauducq 2015-12-20 22:06:07 +08:00
parent 4b5c10b641
commit b96e0d241e
1 changed files with 27 additions and 8 deletions

View File

@ -3,11 +3,8 @@ from collections import namedtuple
from itertools import count from itertools import count
from enum import Enum from enum import Enum
import struct import struct
import importlib
import logging import logging
from artiq.coredevice import ttl
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -110,6 +107,9 @@ class VCDManager:
self.codes = vcd_codes() self.codes = vcd_codes()
self.current_time = None self.current_time = None
def set_timescale_ns(self, timescale):
self.out.write("$timescale {}ns $end\n".format(timescale))
def get_channel(self, name, width): def get_channel(self, name, width):
code = next(self.codes) code = next(self.codes)
self.out.write("$var wire {width} {code} {name} $end\n" self.out.write("$var wire {width} {code} {name} $end\n"
@ -145,13 +145,25 @@ class TTLHandler:
self.channel_value.set_value("X") self.channel_value.set_value("X")
def get_timescale(devices):
timescale = None
for desc in devices.values():
if isinstance(desc, dict) and desc["type"] == "local":
if (desc["module"] == "artiq.coredevice.core"
and desc["class"] == "Core"):
if timescale is None:
timescale = desc["arguments"]["ref_period"]*1e9
else:
return None # more than one core device found
return timescale
def create_channel_handlers(vcd_manager, devices): def create_channel_handlers(vcd_manager, devices):
channel_handlers = dict() channel_handlers = dict()
for name, desc in sorted(devices.items(), key=itemgetter(0)): for name, desc in sorted(devices.items(), key=itemgetter(0)):
if isinstance(desc, dict) and desc["type"] == "local": if isinstance(desc, dict) and desc["type"] == "local":
module = importlib.import_module(desc["module"]) if (desc["module"] == "artiq.coredevice.ttl"
device_class = getattr(module, desc["class"]) and desc["class"] in {"TTLOut", "TTLInOut"}):
if device_class in {ttl.TTLOut, ttl.TTLInOut}:
channel = desc["arguments"]["channel"] channel = desc["arguments"]["channel"]
channel_handlers[channel] = TTLHandler(vcd_manager, name) channel_handlers[channel] = TTLHandler(vcd_manager, name)
return channel_handlers return channel_handlers
@ -162,12 +174,19 @@ def get_message_time(message):
def messages_to_vcd(filename, devices, messages): def messages_to_vcd(filename, devices, messages):
messages = [m for m in messages if get_message_time(m)] # TODO: remove this hack
messages = sorted(messages, key=get_message_time)
vcd_manager = VCDManager(filename) vcd_manager = VCDManager(filename)
try: try:
timescale = get_timescale(devices)
if timescale is not None:
vcd_manager.set_timescale_ns(timescale)
else:
logger.warning("unable to determine VCD timescale")
channel_handlers = create_channel_handlers(vcd_manager, devices) channel_handlers = create_channel_handlers(vcd_manager, devices)
vcd_manager.set_time(0) vcd_manager.set_time(0)
messages = [m for m in messages if get_message_time(m)] # TODO: remove this hack
messages = sorted(messages, key=get_message_time)
if messages: if messages:
start_time = get_message_time(messages[0]) start_time = get_message_time(messages[0])
for message in messages: for message in messages: