forked from M-Labs/artiq
runtime: support clock switching
This commit is contained in:
parent
94218f785e
commit
fc690ead75
|
@ -7,6 +7,7 @@ from fractions import Fraction
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from artiq.language import core as core_language
|
from artiq.language import core as core_language
|
||||||
|
from artiq.language import units
|
||||||
from artiq.coredevice.runtime import Environment
|
from artiq.coredevice.runtime import Environment
|
||||||
from artiq.coredevice import runtime_exceptions
|
from artiq.coredevice import runtime_exceptions
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ class _H2DMsgType(Enum):
|
||||||
LOAD_OBJECT = 2
|
LOAD_OBJECT = 2
|
||||||
RUN_KERNEL = 3
|
RUN_KERNEL = 3
|
||||||
SET_BAUD_RATE = 4
|
SET_BAUD_RATE = 4
|
||||||
|
SWITCH_CLOCK = 5
|
||||||
|
|
||||||
|
|
||||||
class _D2HMsgType(Enum):
|
class _D2HMsgType(Enum):
|
||||||
|
@ -37,6 +39,8 @@ class _D2HMsgType(Enum):
|
||||||
KERNEL_EXCEPTION = 9
|
KERNEL_EXCEPTION = 9
|
||||||
KERNEL_STARTUP_FAILED = 10
|
KERNEL_STARTUP_FAILED = 10
|
||||||
RPC_REQUEST = 11
|
RPC_REQUEST = 11
|
||||||
|
CLOCK_SWITCH_COMPLETED = 12
|
||||||
|
CLOCK_SWITCH_FAILED = 13
|
||||||
|
|
||||||
|
|
||||||
def _write_exactly(f, data):
|
def _write_exactly(f, data):
|
||||||
|
@ -135,12 +139,21 @@ class Comm:
|
||||||
runtime_id += chr(reply)
|
runtime_id += chr(reply)
|
||||||
if runtime_id != "AROR":
|
if runtime_id != "AROR":
|
||||||
raise UnsupportedDevice("Unsupported runtime ID: "+runtime_id)
|
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))
|
">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))
|
logger.debug("environment ref_period: {}".format(ref_period))
|
||||||
return Environment(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):
|
def load(self, kcode):
|
||||||
_write_exactly(self.port, struct.pack(
|
_write_exactly(self.port, struct.pack(
|
||||||
">lblL",
|
">lblL",
|
||||||
|
|
|
@ -42,13 +42,20 @@ def _no_debug_unparse(label, node):
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
def __init__(self, comm, runtime_env=None):
|
def __init__(self, comm, external_clock=None, runtime_env=None):
|
||||||
if runtime_env is None:
|
if runtime_env is None:
|
||||||
runtime_env = comm.get_runtime_env()
|
runtime_env = comm.get_runtime_env()
|
||||||
self.runtime_env = runtime_env
|
self.runtime_env = runtime_env
|
||||||
self.comm = comm
|
self.comm = comm
|
||||||
self.core = self
|
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,
|
def transform_stack(self, func_def, rpc_map, exception_map,
|
||||||
debug_unparse=_no_debug_unparse):
|
debug_unparse=_no_debug_unparse):
|
||||||
lower_units(func_def, rpc_map)
|
lower_units(func_def, rpc_map)
|
||||||
|
@ -57,7 +64,7 @@ class Core:
|
||||||
remove_inter_assigns(func_def)
|
remove_inter_assigns(func_def)
|
||||||
debug_unparse("remove_inter_assigns_1", 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)
|
debug_unparse("quantize_time", func_def)
|
||||||
|
|
||||||
fold_constants(func_def)
|
fold_constants(func_def)
|
||||||
|
@ -69,7 +76,7 @@ class Core:
|
||||||
interleave(func_def)
|
interleave(func_def)
|
||||||
debug_unparse("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)
|
debug_unparse("lower_time", func_def)
|
||||||
|
|
||||||
remove_inter_assigns(func_def)
|
remove_inter_assigns(func_def)
|
||||||
|
|
|
@ -141,11 +141,11 @@ def _debug_dump_obj(obj):
|
||||||
|
|
||||||
|
|
||||||
class Environment(LinkInterface):
|
class Environment(LinkInterface):
|
||||||
def __init__(self, ref_period):
|
def __init__(self, internal_ref_period):
|
||||||
self.cpu_type = "or1k"
|
self.cpu_type = "or1k"
|
||||||
self.ref_period = ref_period
|
self.internal_ref_period = internal_ref_period
|
||||||
# allow 1ms for all initial DDS programming
|
# 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):
|
def emit_object(self):
|
||||||
tm = lt.TargetMachine.new(triple=self.cpu_type, cpu="generic")
|
tm = lt.TargetMachine.new(triple=self.cpu_type, cpu="generic")
|
||||||
|
@ -155,4 +155,4 @@ class Environment(LinkInterface):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Environment {} {}>".format(self.cpu_type,
|
return "<Environment {} {}>".format(self.cpu_type,
|
||||||
str(units.Hz/self.ref_period))
|
str(1/self.ref_period))
|
||||||
|
|
|
@ -11,6 +11,7 @@ enum {
|
||||||
MSGTYPE_LOAD_OBJECT,
|
MSGTYPE_LOAD_OBJECT,
|
||||||
MSGTYPE_RUN_KERNEL,
|
MSGTYPE_RUN_KERNEL,
|
||||||
MSGTYPE_SET_BAUD_RATE,
|
MSGTYPE_SET_BAUD_RATE,
|
||||||
|
MSGTYPE_SWITCH_CLOCK,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* device to host */
|
/* device to host */
|
||||||
|
@ -30,6 +31,9 @@ enum {
|
||||||
MSGTYPE_KERNEL_STARTUP_FAILED,
|
MSGTYPE_KERNEL_STARTUP_FAILED,
|
||||||
|
|
||||||
MSGTYPE_RPC_REQUEST,
|
MSGTYPE_RPC_REQUEST,
|
||||||
|
|
||||||
|
MSGTYPE_CLOCK_SWITCH_COMPLETED,
|
||||||
|
MSGTYPE_CLOCK_SWITCH_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int receive_int(void)
|
static int receive_int(void)
|
||||||
|
@ -169,6 +173,9 @@ void comm_serve(object_loader load_object, kernel_runner run_kernel)
|
||||||
send_int(0x5a5a5a5a);
|
send_int(0x5a5a5a5a);
|
||||||
uart_sync();
|
uart_sync();
|
||||||
uart_tuning_word_write(ftw);
|
uart_tuning_word_write(ftw);
|
||||||
|
} else if(msgtype == MSGTYPE_SWITCH_CLOCK) {
|
||||||
|
rtiocrg_clock_sel_write(receive_char());
|
||||||
|
send_char(MSGTYPE_CLOCK_SWITCH_COMPLETED);
|
||||||
} else
|
} else
|
||||||
send_char(MSGTYPE_MESSAGE_UNRECOGNIZED);
|
send_char(MSGTYPE_MESSAGE_UNRECOGNIZED);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue