mirror of https://github.com/m-labs/artiq.git
pdq2: redo program serialization, cleanup
This commit is contained in:
parent
294eac19fe
commit
7c246b3559
|
@ -23,12 +23,13 @@ class Segment:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.data = b""
|
self.data = b""
|
||||||
|
self.addr = None
|
||||||
|
|
||||||
def line(self, typ, duration, data, trigger=False, silence=False,
|
def line(self, typ, duration, data, trigger=False, silence=False,
|
||||||
aux=False, shift=0, jump=False, clear=False, wait=False):
|
aux=False, shift=0, jump=False, clear=False, wait=False):
|
||||||
assert len(data) % 2 == 0, data
|
assert len(data) % 2 == 0, data
|
||||||
assert len(data)//2 <= 14
|
assert len(data)//2 <= 14
|
||||||
#assert dt*(1 << shift) > 1 + len(data)//2
|
# assert dt*(1 << shift) > 1 + len(data)//2
|
||||||
header = (
|
header = (
|
||||||
1 + len(data)//2 | (typ << 4) | (trigger << 6) | (silence << 7) |
|
1 + len(data)//2 | (typ << 4) | (trigger << 6) | (silence << 7) |
|
||||||
(aux << 8) | (shift << 9) | (jump << 13) | (clear << 14) |
|
(aux << 8) | (shift << 9) | (jump << 13) | (clear << 14) |
|
||||||
|
@ -92,7 +93,7 @@ class Channel:
|
||||||
self.segments = []
|
self.segments = []
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
del self.segments[:]
|
self.segments.clear()
|
||||||
|
|
||||||
def new_segment(self):
|
def new_segment(self):
|
||||||
segment = Segment()
|
segment = Segment()
|
||||||
|
@ -149,10 +150,6 @@ class Pdq2:
|
||||||
self.dev.close()
|
self.dev.close()
|
||||||
del self.dev
|
del self.dev
|
||||||
|
|
||||||
def clear_all(self):
|
|
||||||
for channel in self.channels:
|
|
||||||
channel.clear()
|
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
logger.debug("> %r", data)
|
logger.debug("> %r", data)
|
||||||
written = self.dev.write(data)
|
written = self.dev.write(data)
|
||||||
|
@ -172,30 +169,11 @@ class Pdq2:
|
||||||
data = data.replace(self._escape, self._escape + self._escape)
|
data = data.replace(self._escape, self._escape + self._escape)
|
||||||
self.write(data)
|
self.write(data)
|
||||||
|
|
||||||
def write_channel(self, channel):
|
def flush(self):
|
||||||
self.write_mem(self.channels.index(channel),
|
self.dev.flush()
|
||||||
channel.serialize())
|
|
||||||
|
|
||||||
def write_all(self):
|
def program_segments(self, segments, data):
|
||||||
for channel in self.channels:
|
for i, line in enumerate(data):
|
||||||
self.write_mem(self.channels.index(channel),
|
|
||||||
channel.serialize())
|
|
||||||
|
|
||||||
def write_table(self, channel):
|
|
||||||
# no segment placement
|
|
||||||
# no segment writing
|
|
||||||
self.write_mem(channel, self.channels[channel].table())
|
|
||||||
|
|
||||||
def write_segment(self, channel, segment):
|
|
||||||
# no collision check
|
|
||||||
s = self.channels[channel].segments[segment]
|
|
||||||
self.write_mem(channel, s.data, s.adr)
|
|
||||||
|
|
||||||
def program_frame(self, frame_data):
|
|
||||||
segments = [c.new_segment() for c in self.channels]
|
|
||||||
for segment in segments:
|
|
||||||
segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1)
|
|
||||||
for i, line in enumerate(frame_data): # segments are concatenated
|
|
||||||
dac_divider = line.get("dac_divider", 1)
|
dac_divider = line.get("dac_divider", 1)
|
||||||
shift = int(log(dac_divider, 2))
|
shift = int(log(dac_divider, 2))
|
||||||
if 2**shift != dac_divider:
|
if 2**shift != dac_divider:
|
||||||
|
@ -210,19 +188,26 @@ class Pdq2:
|
||||||
getattr(segment, target)(
|
getattr(segment, target)(
|
||||||
shift=shift, duration=duration, trigger=trigger,
|
shift=shift, duration=duration, trigger=trigger,
|
||||||
**target_data)
|
**target_data)
|
||||||
|
|
||||||
|
def program(self, program, channels=None):
|
||||||
|
if channels is None:
|
||||||
|
channels = range(self.num_channels)
|
||||||
|
chs = [self.channels[i] for i in channels]
|
||||||
|
for channel in chs:
|
||||||
|
channel.clear()
|
||||||
|
for frame in program:
|
||||||
|
segments = [c.new_segment() for c in chs]
|
||||||
|
for segment in segments:
|
||||||
|
segment.line(typ=3, data=b"", trigger=True, duration=1, aux=1)
|
||||||
|
self.program_segments(segments, frame)
|
||||||
# append an empty line to stall the memory reader before jumping
|
# append an empty line to stall the memory reader before jumping
|
||||||
# through the frame table (`wait` does not prevent reading
|
# through the frame table (`wait` does not prevent reading
|
||||||
# the next line)
|
# the next line)
|
||||||
for segment in segments:
|
for segment in segments:
|
||||||
segment.line(typ=3, data=b"", trigger=True, duration=1,
|
segment.line(typ=3, data=b"", trigger=True, duration=1, aux=1,
|
||||||
jump=True, aux=1)
|
jump=True)
|
||||||
return segments
|
for channel, ch in zip(channels, chs):
|
||||||
|
self.write_mem(channel, ch.serialize())
|
||||||
def program(self, program):
|
|
||||||
self.clear_all()
|
|
||||||
for frame_data in program:
|
|
||||||
self.program_frame(frame_data)
|
|
||||||
self.write_all()
|
|
||||||
|
|
||||||
def ping(self):
|
def ping(self):
|
||||||
return True
|
return True
|
||||||
|
|
Loading…
Reference in New Issue