lekernel changed the topic of #m-labs to: Mixxeo, Migen, MiSoC & other M-Labs projects :: fka #milkymist :: Logs http://irclog.whitequark.org/m-labs
<sb0>
rjo, so the same frame number potentially selects a different waveform at each PDQ and each DAC?
<rjo>
sb0: yes. we usually think of the dacs as a single multi-channel bank.
<sb0>
and is there any sort of clock synchronization between the DDS and the PDQ to avoid jitter due to the asynchronous trigger, or do we just live with the jitter?
<rjo>
sb0: in this case live with the jitter. lets say its 2 cycles, 20ns, the analog lowpasses after the dacs are usually >1µs
<sb0>
ok. and are there going to be frame numbers that are NOPs for some DACs (i.e. keep the previous waveform), or does every pulse on frame select a new waveform for every DAC?
<sb0>
of course the new waveform could be programmed to be the same as the old one. but then we have to worry about keeping the phase continuous...
<rjo>
frame selects the frame that is to be played next.
<rjo>
phase?
<sb0>
let's say you have a DAC generating the same low-frequency waveform in frame #1 and #2. when you switch, you may not want that waveform to be disturbed.
<rjo>
sb0: changes in frame do not abort the current waveform.
<rjo>
sb0: frame is only used as the index into the jump table when the current frame is done.
<sb0>
oh, ok. so the frame change resolution is actually pretty low.
<rjo>
sb0: in practice yes. technically it is "one line" which can be as short as a handful of cycles.
<rjo>
but in practice it is tens of µs.
<rjo>
at least
<rjo>
in the old version changes in frame (aka "branch" back then) would abort a waveform. but that is pretty much never the right thing to do.
<sb0>
so, I imagine an API where you register frames as complete sets of waveforms for each DAC
<sb0>
the API gives you a number, which you store, and use in kernel
<rjo>
sb0: a "handle". yes.
<sb0>
we can directly use the frame number...
<sb0>
(that is output on the TTL lines)
<rjo>
sb0: yes
<rjo>
in practice we sometimes have just a single frame (the frame signals always pulled low) and do need the ability to switch between frames. in any case an .append()-like method for frames would be useful that adds a synchronisation pulse and then appends another part of the waveform to the current frame.
<sb0>
"do need the ability to switch between frames"?
<rjo>
s/do/do not/
<sb0>
ok. and what do you mean by append another part of the waveform to the frame?
<sb0>
the API should support building the frame one DAC waveform at a time?
<rjo>
sb0: building the waveform programmatically. like:
<sb0>
eg. x = register_frame(); x.add_waveform("electrode1", ...); x.add_waveform("electrode2", ...);
<sb0>
but waveform_a and waveform_b are two different frames, right?
<rjo>
with "electrodes = pdq.get_frame()" or your "register_frame()"
<rjo>
sb0: no. they are different parts of the same waveform: like transport from A to B and then transport from B to C)
<rjo>
sb0: transport = electrodes.get_frame(index=None); bd.pulse(1*us); transport.play(waveform_a); bd.pulse(1*us); transport.play(waveform_b)
<sb0>
so the bd.pulse delays should be automatically added to the waveform?
<rjo>
get_frame() is your register_frame() in this case auto-selects an unused index, emits setting of the frame lines to said index at the right time. pulses trigger line at the beginning of play(waveform_a) and at the beginning of play(waveform_b).
elaforest has quit [Ping timeout: 260 seconds]
<sb0>
and how does the PDQ know which waveform to play?
<sb0>
since you said it's one frame, and the frame selection lines are always pulled low.
<rjo>
sb0: does not matter in this case. the play() just appends to the frame and inserts a pulse(trigger, 0.1*us) at the right time on the core rtio
<rjo>
sb0: in the case where we did not wire the frame select to the rtio, allow only frame 0, else get an unused frame, set the frame lines to the index and pulse trigger when the waveform should start.
<sb0>
but there are two waveforms: waveform_a and waveform_b
<sb0>
I'd put each in a separate frame
<rjo>
sb0: if we are lazy or ran out of ttl lines, we only have one frame available. then we want the two waveforms end up in the same frame.
<sb0>
and when the trigger line is pulsed, how does the PDQ know which of waveform_a and waveform_b to play then?
<rjo>
sb0: lets define for this discussion a frame to be composed of several waveforms, each waveform to be composed of several lines.
<rjo>
sb0: depends on which line it is currently waiting for a trigger.
<rjo>
sb0: a line is header+data. header has flags to wait for trigger high before and/or after this line.
<sb0>
this line stuff looks rather complicated, more than having N TTL lines for 2**N frames ...
<rjo>
sb0: line could also have been called "spline knot".
<rjo>
sb0: each frame needs to consist of multiple smaller things. call them "lines" or "knots". knots is a bit misleading since they can also contain more or less than the spline knot data.
<sb0>
if the frame selection signals are tied low, how do you tell the PDQ to go back to the start of the frame?
<rjo>
sb0: it does so by itself if it sees a line with "end" in its header.
<rjo>
sb0: then it jumps into the jump table.
<sb0>
and this never goes out of sync?
<sb0>
this looks a bit fragile. any glitch on trigger, and the PDQs silently fail until they are reprogrammed.
<rjo>
sb0: it is by as much as the waveform length times how much the crystals have different frequencies relative to our maser.
<rjo>
sb0: it also jumps back to the jump table on ~arm.
<rjo>
well. if a trigger glitches, anything attached to it will do what it is supposed to do on trigger. that is nothing special.
<sb0>
I don't see this arm signal in your platform file
<rjo>
and not specific to the pdqs.
<sb0>
btw, I think it's easier to understand if you split the "comm" IO block into USB and TTL parts
<rjo>
like for transport_destination in range(3, 10): setup_transport_waveforms(); for n in range(self.nrepeats)
<rjo>
...
<sb0>
ok. and we can either have to core device RPC the setup_transport_waveforms(), or run the outer loop on the host and break out " for n in range(self.nrepeats)...." into a kernel
<rjo>
it might be best if i hack together an example experiment.
<rjo>
exactly.
<rjo>
sb0: i'll put together an example experiment tomorrow.
<sb0>
ok, thanks :)
<rjo>
sb0: you said your office is is downtown. is it also "occupied"?
<rjo>
;)
<rjo>
s/is is/is/
<sb0>
no, the protests didn't spread out west that much
<sb0>
but it's close
<rjo>
sb0: and the protests are not yet over, are they?
<sb0>
no. still going strong. I checked them out yesterday evening, still roughly the same amount of people, with more tents and banners
<rjo>
hmm. this may (or may not) become a historic moment. i wonder whether it was obvious during the "monday demonstrations" 1989/1990 in germany that they were historic...
<sb0>
most hongkongers seem to call them highly unusual, if not historic
<sb0>
what exactly is the "wait for low trigger after" feature? isn't it equivalent to waiting for the next trigger pulse?
<sb0>
or is the PDQ trigger level sensitive, not edge sensitive?
<sb0>
this python asyncio stuff is rather messy. eg try unpickling an object from a StreamReader ...
_florent_ has quit [Quit: Leaving]
mumptai has joined #m-labs
xiangfu has quit [Remote host closed the connection]
kyak has quit [Ping timeout: 272 seconds]
kyak has joined #m-labs
kyak has joined #m-labs
<stekern>
sb0: do you have project where you tested to build the riscv core on s6 to share?
aeris has quit [Quit: en a pas]
aeris has joined #m-labs
<rjo>
sb0: the "trigger low" comment is outdated. "wait" and "trigger" both wait for the trigger signal high. level sensitive.
<rjo>
sb0: the different meanings (wait before and wait after) become useful if you want to wait before jumping back into the jump table (set frame then trigger, ...) or if you want to have a part of the waveform started on a trigger without having to modify whatever preceded that part.
<rjo>
sb0: i would be interested in having a decent resolution wideband spectrograph with a multimode fiber input. no need for the raman excitation stuff.
<rjo>
sb0: as with most asynchronous frameworks, seeing through and digesting the design philosophy is tedious. what is the difficulty with getting pickles from a streamreader? buffering issues?