From fc690ead754e4b8e447f94c34d1b97b97ea92013 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 2 Dec 2014 14:06:32 +0800 Subject: [PATCH] runtime: support clock switching --- artiq/coredevice/comm_serial.py | 17 +++++++++++++++-- artiq/coredevice/core.py | 13 ++++++++++--- artiq/coredevice/runtime.py | 8 ++++---- soc/runtime/comm_serial.c | 7 +++++++ 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/artiq/coredevice/comm_serial.py b/artiq/coredevice/comm_serial.py index e9c1794e0..d87a99e05 100644 --- a/artiq/coredevice/comm_serial.py +++ b/artiq/coredevice/comm_serial.py @@ -7,6 +7,7 @@ from fractions import Fraction import logging from artiq.language import core as core_language +from artiq.language import units from artiq.coredevice.runtime import Environment from artiq.coredevice import runtime_exceptions @@ -23,6 +24,7 @@ class _H2DMsgType(Enum): LOAD_OBJECT = 2 RUN_KERNEL = 3 SET_BAUD_RATE = 4 + SWITCH_CLOCK = 5 class _D2HMsgType(Enum): @@ -37,6 +39,8 @@ class _D2HMsgType(Enum): KERNEL_EXCEPTION = 9 KERNEL_STARTUP_FAILED = 10 RPC_REQUEST = 11 + CLOCK_SWITCH_COMPLETED = 12 + CLOCK_SWITCH_FAILED = 13 def _write_exactly(f, data): @@ -135,12 +139,21 @@ class Comm: runtime_id += chr(reply) if runtime_id != "AROR": raise UnsupportedDevice("Unsupported runtime ID: "+runtime_id) - (ref_freq_i, ref_freq_fn, ref_freq_fd) = struct.unpack( + ref_freq_i, ref_freq_fn, ref_freq_fd = struct.unpack( ">lBB", _read_exactly(self.port, 6)) - ref_period = 1/(ref_freq_i + Fraction(ref_freq_fn, ref_freq_fd)) + ref_freq = (ref_freq_i + Fraction(ref_freq_fn, ref_freq_fd))*units.Hz + ref_period = 1/ref_freq logger.debug("environment ref_period: {}".format(ref_period)) return Environment(ref_period) + def switch_clock(self, external): + _write_exactly(self.port, struct.pack( + ">lbb", 0x5a5a5a5a, _H2DMsgType.SWITCH_CLOCK.value, + int(external))) + msg = self._get_device_msg() + if msg != _D2HMsgType.CLOCK_SWITCH_COMPLETED: + raise IOError("Incorrect reply from device: "+str(msg)) + def load(self, kcode): _write_exactly(self.port, struct.pack( ">lblL", diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index 1e578c650..58695c803 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -42,13 +42,20 @@ def _no_debug_unparse(label, node): class Core: - def __init__(self, comm, runtime_env=None): + def __init__(self, comm, external_clock=None, runtime_env=None): if runtime_env is None: runtime_env = comm.get_runtime_env() self.runtime_env = runtime_env self.comm = comm self.core = self + if external_clock is None: + self.ref_period = self.runtime_env.internal_ref_period + self.comm.switch_clock(False) + else: + self.ref_period = external_clock + self.comm.switch_clock(True) + def transform_stack(self, func_def, rpc_map, exception_map, debug_unparse=_no_debug_unparse): lower_units(func_def, rpc_map) @@ -57,7 +64,7 @@ class Core: remove_inter_assigns(func_def) debug_unparse("remove_inter_assigns_1", func_def) - quantize_time(func_def, self.runtime_env.ref_period) + quantize_time(func_def, self.ref_period.amount) debug_unparse("quantize_time", func_def) fold_constants(func_def) @@ -69,7 +76,7 @@ class Core: interleave(func_def) debug_unparse("interleave", func_def) - lower_time(func_def, self.runtime_env.initial_time) + lower_time(func_def, self.runtime_env.warmup_time/self.ref_period) debug_unparse("lower_time", func_def) remove_inter_assigns(func_def) diff --git a/artiq/coredevice/runtime.py b/artiq/coredevice/runtime.py index 2e8884022..e0157934e 100644 --- a/artiq/coredevice/runtime.py +++ b/artiq/coredevice/runtime.py @@ -141,11 +141,11 @@ def _debug_dump_obj(obj): class Environment(LinkInterface): - def __init__(self, ref_period): + def __init__(self, internal_ref_period): self.cpu_type = "or1k" - self.ref_period = ref_period + self.internal_ref_period = internal_ref_period # allow 1ms for all initial DDS programming - self.initial_time = int(Fraction(1, 1000)/self.ref_period) + self.warmup_time = 1*units.ms def emit_object(self): tm = lt.TargetMachine.new(triple=self.cpu_type, cpu="generic") @@ -155,4 +155,4 @@ class Environment(LinkInterface): def __repr__(self): return "".format(self.cpu_type, - str(units.Hz/self.ref_period)) + str(1/self.ref_period)) diff --git a/soc/runtime/comm_serial.c b/soc/runtime/comm_serial.c index 9addfb608..7cdceef54 100644 --- a/soc/runtime/comm_serial.c +++ b/soc/runtime/comm_serial.c @@ -11,6 +11,7 @@ enum { MSGTYPE_LOAD_OBJECT, MSGTYPE_RUN_KERNEL, MSGTYPE_SET_BAUD_RATE, + MSGTYPE_SWITCH_CLOCK, }; /* device to host */ @@ -30,6 +31,9 @@ enum { MSGTYPE_KERNEL_STARTUP_FAILED, MSGTYPE_RPC_REQUEST, + + MSGTYPE_CLOCK_SWITCH_COMPLETED, + MSGTYPE_CLOCK_SWITCH_FAILED, }; static int receive_int(void) @@ -169,6 +173,9 @@ void comm_serve(object_loader load_object, kernel_runner run_kernel) send_int(0x5a5a5a5a); uart_sync(); uart_tuning_word_write(ftw); + } else if(msgtype == MSGTYPE_SWITCH_CLOCK) { + rtiocrg_clock_sel_write(receive_char()); + send_char(MSGTYPE_CLOCK_SWITCH_COMPLETED); } else send_char(MSGTYPE_MESSAGE_UNRECOGNIZED); }