AXIS Generator#
This module is the Custom IP used to generate the waves for readout and control.
This is the fully fledged version of the generator, which integrates envelope interpolation capabilities.
This generator can generate both the drive and readout waves for a q-bit since the readout wave is generated only once all drive waves have finished generating.
This generator also supports Virtual Z Gates in hardware.
Supported Gates#
This generator generates a wave which is defined as a finite sequence of 16-bit signed samples generated based on some criteria. The generation criteria is defined in a wave word which is passed to the generator by means of the input communication interfaces.
Properly defined waves are used as gates thus the words gate and wave are used interchangeably in this document.
Different types of gates may reuse the same resources or require a completely different control schema, thus the following gates are natively supported:
X-gates: basic wave, uses an I/Q envelope stored in memory and it’s modulated at the drive frequency.
Y-gates: same as the X-gate but can use the same I/Q envelope used for X-gates by switching the I and Q samples of the envelope. This is supported in hardware (see later).
Virtual Z-gates: this type of gate is supported in hardware such that all subsequent waves will have a phase shift.
the phase shift of the VZ-gate is accumulated and subsequent VZ-gates add to the previous value.
the phase shift is reset at experiment start or restart (new experiment or new shot).
Communication Interfaces#
This module has two AXI input interfaces:
one Lite interface which is used to control the generator directly from the PS and to set some generation parameters.
one Full interface to fill the memory of the embedded sample generator (see
sample_generator/readme.md) and wave sequencer (seegenerator_sequencer/readme.md).
Two AXI Stream output interfaces:
one stream output to the drive (see
crossbar_matrix/readme.md) or readout zone (frequency_multiplexer/readme.md).
In its standard configuration, they both generate 16 samples (16-bits each) per clock cycle.
The AXI Stream interface currently supports the tvalid signal, active whenever a signal is generated in the sample_generator.
The interface supports also the 16-bit tuser signal:
Bit [15] (MSB): set when a readout trigger or a manual trigger with
manual_selector_o=1is active; cleared for drive.Bits [14:0]: 15-bit DAC destination mask, set through bits [118:104] of the Wave Definition Word (see later).
Finally, this module has two N-bit parallel (up to 15) input called drive_external_trigger and readout_external_trigger.
These inputs are used in combination with the trigger generator to handle the necessary wave generation timing requirements for the drive waves and readout waves respectively.
Waves can, in fact, either be triggered via the PS using the AXI Lite interface or by the *_external_trigger inputs.
The generator can be set to listen to one of the bits of the trigger input word and will start generating samples when the correct bit goes high.
Mode of Operation#
This generator uses the sample generator located under the sample_generator/ directory to generate the envelope samples and uses the sine cosine generator under the dds_gen/ as a free-running, variable frequency and phase local oscillator.
In the context of the generator an experiment consists of:
a set of UNIQUE drive gates to be generated
the order of generation of the drive gates
a readout wave
During an experiment, the drive frequency is fixed and the drive phase offset can only be changed by means of Virtual Z gates.
The built in sequencer stores the set of unique drive gates in its wave memory and the sequence in its memory mapped fifo:
the wave memory is loaded with the wave definion words for each gate (see later)
the memory mapped FIFO is loaded with the addresses used to index the wave memory
the memory mapped FIFO is automatically traversed from start to finish in a fifo like manner
it stores 1-byte addresses since there are 256 unique waves that can be stored in the wave memory
alternatively, one can choose to load gates from the wave memory randomically, using the built-in LFSR
EXAMPLE: suppose we want to send a X-pi/2 gate followed by a X-pi gate followed by a X-pi/2 gate. There are 2 unique gates, each needing a wave definition word. Suppose we write the X-pi/2 word into the wave memory at address 0 and the X-pi word into the wave memory at address 80, then, the memory mapped fifo would require to be filled with 0 at address 0, 80 at address 1 and 0 at address 2.
In this example, when the experiment is started or restarted, the read pointer of the memory mapped fifo is reset to 0 and the first wave word is read. When a drive trigger is received, the gate is launched and the next wave word is read, ready to be sent at the next trigger.
This behaviour will repeat until the experiment is started/restarted (in case of many shots).
In case that the LFSR is selected, the behaviour is the same but the LFSR is used to address the wave memory. The LFSR is loaded with a configurable seed at the start/restart of an experiment and it’s advanced any time a trigger is received.
Once all the drive gates are generated, when a readout trigger is received, the readout wave is sent.
The readout frequency, phase offset and wave definition word can be configured using the AXI Lite interface (see later).
Triggers#
The IP will start the generation of a wave when triggered.
There are tree trigger sources controlling the generation:
Manual trigger, via the AXI Lite.
External drive trigger, via the trigger interface. The N-bit drive trigger input is compared with the drive trigger mask set via the AXI Lite interface.
External readout trigger, via the trigger interface. The N-bit readout trigger input is compared with the readout trigger mask set via the AXI Lite interface.
The manual trigger will always generate the readout wave defined by the readout word, frequency and phase offset but the wave generated can be either a readout or drive wave (see later).
NOTE: external triggers must be single clock cycle pulses otherwise the generator will be triggered multiple times. A trigger word made up of all zeros is invalid and will not trigger the generator.
EXAMPLE: if the external trigger word is 0001 and the mask is set as 0100, the generator will not start. If the trigger word is 0100, the generator will start. If the trigger word is 0000, the generator will never trigger even if the trigger mask is equal to 0000, but you can still manually trigger it.
WARNING: triggers have to be generated such that:
triggers on different sources must not overlap
triggers on different or same sources must wait at least one clock cycle between them
triggers must wait for the generation of a wave to end:
this does not include the latency of the generator
the wait period (in clock cycles) can be calculated as duration/16
AXI Stream output channels#
Depending on the type of trigger received by the generator, the drive or readout output channel will be active whereas the other one will have it’s value set to zero.
The triggers have the following hierarchy:
external readout trigger: will generate the defined readout wave.
manual trigger: will generate the defined readout wave for readout or drive depending on the control setting.
external drive trigger: will generate a wave defined by the internal wave sequencer for the drive.
In case that more than one trigger is received (which should never happen), the trigger that is highest on this list has higher priority. Note that the lower priority triggers are lost.
Notice that for all the previous configurations, an additional priority logic sets the MSB of the tuser as defined in the Communication Interfaces section. The remaining 15 bits are set through the WDW (see next section).
Wave Definition Word#
The wave definition word is the collection of all the signals needed by the IP to correctly generate a wave.
The generator will read a wave definition word from two possible sources:
The AXI Lite Interface, for readout or manual triggers
The internal sequencer, only for drive triggers depending on the trigger source defined above.
The wave word is 128-bit wide and is mapped in the following way:
bit 127: simmetric bit, used when interpolating, tells the generator that the envelope memory is symmetric.
bit 126: I even bit, tells the generator that the wave has even simmetry on the in-phase values.
bit 125: Q even bit, same as above but with quadrature values.
bit 124: invert bit, inverts the sign of the generator’s output.
bit 123: invert sin cos bit, uses Q as I and vice-versa. Used to send Y gates without changing the envelope.
bit 122: keep last bit, keeps the last samples at the output of the generator.
bit 121: force one bit, forces the envelope to be I = 1 and Q = 0. Used to send rectangular waves or tones.
bit 120: interpolate bit, tells the generator to use interpolation for the envelope generation.
bit 119: is VZ Gate bit, tells the generator that this is a virtual Z gate.
bit 118 to 104: dac mask, select the destination dac, for example: bit 104 selects dac0, bit 118 selects dac15
Notice that, if the overlay support only two dacs, then the user must sets only the bits 104 and 105, and puts all the others to 0.
Depending on bit 119, the rest of the wave word has different meaning:
if not VZ Gate:
bit 0 to 35: envelope increment (see
sample_gen/readme.md).bit 36 to 71: envelope start offset.
bit 72 to 87: wave max duration.
bit 88 to 103: 16-bit unsigned gain.
if VZ Gate:
bit 0 to 47: Z phase offset in RAD, 48-bit unsigned mapped into [0:2pi[.
bit 48 to 127: MUST be set to zero, except for bit 119 which must be set to 1.
AXI LITE Register Map#
The AXI Lite interface is used to set some control parameters and other parameters that are constant throughout an experiment.
All register numbers are given as 32-bit aligned indexes, thus register #0 is the register at AXI address “0 + axi_lite_start_address” while register #1 is the register at AXI address “4 + axi_lite_start_address”.
All AXI Lite registers are 32-bit but some parameters require a wider width. For those parameters, more that one register number will be provided with little endian formatting.
control register, register #0:
bit 0 to 8 (W/R): LFSR seed
bit 9 to 26 (W/R): reserved for future use.
bit 27 (W/R): LFSR or FIFO, if set the wave memory will read depending on the output of the LFSR.
bit 28 (W/R): manual trigger selector. If set to 1 it will output the readout wave (see later), otherwise it will output the drive.
bit 29 (RO): readout DAC tready (for debug).
bit 30 (RO): drive DAC tready (for debug).
bit 31 (W/R): manual trigger.
readout wave word, register #1-2-3-4:
bit 0 to 127: wave word, as defined previously.
readout phase increment, register #5-6:
bit 0 to 47: readout frequency in RAD/SAMPLE, 48-bit unsigned mapped into [0:2pi[/SAMPLE.
drive phase increment, register #7-8:
bit 0 to 47: drive frequency in RAD/SAMPLE, 48-bit unsigned mapped into [0:2pi[/SAMPLE.
readout phase offset, register #9-10:
bit 0 to 47: readout phase offset in RAD, 48-bit unsigned mapped into [0:2pi[.
trigger mask, register 11:
bit 0 to (TriggerWordWidth): drive trigger mask
bit (TriggerWordWidth+1) to (2*TriggerWordWidth): readout trigger mask
bit (2*TriggerWordWidth+1) to 31: reserved for future use
Notice that TriggerWordWidth can be set to be up to 15 (see common_includes/COMMON_INCLUDES.vh).
Example: to write the readout phase offset with a value X, you would first need to write the least significant 32 bits to register 9:
multiply the register number by 4 to get the axi lite offset in bytes
write to the axi lite interface -> mmio.write(bytes_offset, X & 0xFFFFFFFF)
Then, write the high part of the value to register number 10.
AXI FULL Memory Map#
The AXI Full provides an interface to access the memory elements of the Generator IP.
There are 3 distinct memory segments in the IP:
Sample memory, also sometimes referred to as envelope memory.
Sequencer Wave memory, where wave definition words for the drive channel are stored.
Sequencer memory mapped FIFO, where the wave sequence is stored.
These memory segments are contiguos and in the same order as presented in the list.
All accesses to these segments shall be 32-bit aligned, even if the write data is much smaller, in which case, only the least significant digits will be written to the memory and the rest will be discarded (like the memory mapped FIFO).
WARNING: reading from the axi full interface is not suppported, you will always receive the number 0x00000000 if you do.
For information about the sample memory segment and its mapping, see sample_gen/readme.md.
Note that the wave memory of the internal sequencer has a write port that is 32-bit wide and the read port is 128-bit wide.
Each wave definition requires 4 writes to the wave memory with little endian formatting.
EXAMPLE: given a valid 128-bit wave definition, to place it at read address “1”, the 32 least significant bits have to be written at AXI address “1*(4+0)*4 + wave_memory_start_address” (remember that axi addresses are BYTE aligned but we are writing WORDS), the next shall be written to address “1*(4+1)*4 + wave_memory_start_address” and so on until the most significant 32 bits at address “1*(4+3)*4 + wave_memory_start_address”.
In this example, from the point of view of the sequencer memory mapped FIFO, the correct address to read this wave definition word from is “1”.
Drivers#
To easily operate this IP on PYNQ overlays, drivers are available for download in the FIREQ Tools repository.
Drivers provide a good abstraction layer that will let you set up and use the IP without going into details on the implementation.
Creating the AXIS GENERATOR IP PROJECT#
To generate a copy of the axi generator ip project a tcl script is provided:
create a directory called
workspace/in the root of this repomove to that directory and source the vivado init script
open vivado
source the
generator_project.tclscript located in this directory from the vivado tcl console
Set AxisGeneratorIP.v as the top module for synthesis and implementation; otherwise, use generatorIPTestBench.sv to simulate with Vivado’s AXI VIP masters to send data to the generator.