runtime: support clock switching

This commit is contained in:
Sebastien Bourdeauducq 2014-12-02 14:06:32 +08:00
parent 94218f785e
commit fc690ead75
4 changed files with 36 additions and 9 deletions

View File

@ -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",

View File

@ -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)

View File

@ -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 "<Environment {} {}>".format(self.cpu_type,
str(units.Hz/self.ref_period))
str(1/self.ref_period))

View File

@ -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);
}