Code Documentation

host.cli module

PDQ2 frontend.
Evaluates times and voltages, interpolates and uploads them.

usage: pdq2 [-h] [-s SERIAL] [-c CHANNEL] [-f FRAME] [-t TIMES] [-v VOLTAGES]
            [-o ORDER] [-u DUMP] [-r] [-m] [-n] [-e] [-d]

Named Arguments

-s, –serial

device url [“hwgrep://”]

Default: “hwgrep://”

-c, –channel

channel: 3*board_num+dac_num [0]

Default: 0

-f, –frame

frame [0]

Default: 0

-t, –times

sample times (s) [“np.arange(5)*1e-6”]

Default: “np.arange(5)*1e-6”

-v, –voltages

sample voltages (V) [“(1-np.cos(t/t[-1]*2*np.pi))/2”]

Default: “(1-np.cos(t/t[-1]*2*np.pi))/2”

-o, –order

interpolation (0: const, 1: lin, 2: quad, 3: cubic) [3]

Default: 3

-u, –dump dump to file [None]
-r, –reset

do reset before

Default: False

-m, –multiplier
 

100MHz clock [False]

Default: False

-n, –disarm

disarm group [False]

Default: False

-e, –free

software trigger [False]

Default: False

-d, –debug

debug communications

Default: False

host.cli.main(dev=None)[source]

Test a PDQ2 stack.

Parse command line arguments, configures PDQ2 stack, interpolate the time/voltage data using a spline, generate a wavesynth program from the data and upload it to the specified channel. Then perform the desired arming/triggering/starting functions on the stack.

host.pdq2 module

class host.pdq2.Channel[source]

PDQ2 Channel.

num_frames

int – Number of frames supported.

max_data

int – Number of 16 bit data words per channel.

segments

list[Segment] – Segments added to this channel.

clear()[source]

Remove all segments.

new_segment()[source]

Create and attach a new Segment to this channel.

Returns:Segment
place()[source]

Place segments contiguously.

Assign segment start addresses and determine length of data.

Returns:Amount of memory in use on this channel.
Return type:addr (int)
serialize(entry=None)[source]

Serialize the memory for this channel.

Places the segments contiguously in memory after the frame table. Allocates and assigns segment and frame table addresses. Serializes segment data and prepends frame address table.

Parameters:entry (list[Segment]) – See table().
Returns:Channel memory data.
Return type:data (bytes)
table(entry=None)[source]

Generate the frame address table.

Unused frame indices are assigned the zero address in the frame address table. This will cause the memory parser to remain in the frame address table until another frame is selected.

The frame entry segments can be any segments in the channel.

Parameters:entry (list[Segment]) – List of initial segments for each frame. If not specified, the first num_frames segments are used as frame entry points.
Returns:Frame address table.
Return type:table (bytes)
class host.pdq2.Pdq2(url=None, dev=None, num_boards=3)[source]

PDQ stack.

Parameters:
  • url (str) – Pyserial device URL. Can be hwgrep:// style (search for serial number, bus topology, USB VID:PID combination), COM15 for a Windows COM port number, /dev/ttyUSB0 for a Linux serial port.
  • dev (file-like) – File handle to use as device. If passed, url is ignored.
  • num_boards (int) – Number of boards in this stack.
num_dacs

int – Number of DAC outputs per board.

num_channels

int – Number of channels in this stack.

num_boards

int – Number of boards in this stack.

channels

list[Channel] – List of Channel in this stack.

close()[source]

Close the USB device handle.

cmd(cmd, enable)[source]

Execute a command.

Parameters:
  • cmd (str) – Command to execute. One of (RESET, TRIGGER, ARM, DCM, START).
  • enable (bool) – Enable (True) or disable (False) the feature.
program(program, channels=None)[source]

Serialize a wavesynth program and write it to the channels in the stack.

The Channel targeted are cleared and each frame in the wavesynth program is appended to a fresh set of Segment of the channels. All segments are allocated, the frame address tale is generated, the channels are serialized and their memories are written.

Short single-cycle lines are prepended and appended to each frame to allow proper write interlocking and to assure that the memory reader can be reliably parked in the frame address table. The first line of each frame is mandatorily triggered.

Parameters:
  • program (list) – Wavesynth program to serialize.
  • channels (list[int]) – Channel indices to use. If unspecified, all channels are used.
program_segments(segments, data)[source]

Append the wavesynth lines to the given segments.

Parameters:
  • segments (list[Segment]) – List of Segment to append the lines to.
  • data (list) – List of wavesynth lines.
write(data)[source]

Write data to the PDQ2 board.

Parameters:data (bytes) – Data to write.
write_mem(channel, data, start_addr=0)[source]

Write to channel memory.

Parameters:
  • channel (int) – Channel index to write to. Assumes every board in the stack has num_dacs DAC outputs.
  • data (bytes) – Data to write to memory.
  • start_addr (int) – Start address to write data to.
class host.pdq2.Segment[source]

Serialize the lines for a single Segment.

max_time

int – Maximum duration of a line.

max_val

int – Maximum absolute value (scale) of the DAC output.

max_out

float – Output voltage at max_val. In Volt.

out_scale

float – Steps per Volt.

cordic_gain

float – CORDIC amplitude gain.

addr

int – Address assigned to this segment.

data

bytes – Serialized segment data.

bias(amplitude=[], **kwargs)[source]

Append a bias line to this segment.

Parameters:
  • amplitude (list[float]) – Amplitude coefficients in in Volts and increasing powers of 1/(2**shift*clock_period). Discrete time compensation will be applied.
  • **kwargs – Passed to line().
dds(amplitude=[], phase=[], **kwargs)[source]

Append a DDS line to this segment.

Parameters:
  • amplitude (list[float]) – Amplitude coefficients in in Volts and increasing powers of 1/(2**shift*clock_period). Discrete time compensation and CORDIC gain compensation will be applied by this method.
  • phase (list[float]) – Phase/frequency/chirp coefficients. phase[0] in turns, phase[1] in turns/clock_period, phase[2] in turns/(clock_period**2*2**shift).
  • **kwargs – Passed to line().
line(typ, duration, data, trigger=False, silence=False, aux=False, shift=0, jump=False, clear=False, wait=False)[source]

Append a line to this segment.

Parameters:
  • typ (int) – Output module to target with this line.
  • duration (int) – Duration of the line in units of clock_period*2**shift.
  • data (bytes) – Opaque data for the output module.
  • trigger (bool) – Wait for trigger assertion before executing this line.
  • silence (bool) – Disable DAC clocks for the duration of this line.
  • aux (bool) – Assert the AUX (F5 TTL) output during this line.
  • shift (int) – Duration and spline evolution exponent.
  • jump (bool) – Return to the frame address table after this line.
  • clear (bool) – Clear the DDS phase accumulator when starting to exectute this line.
  • wait (bool) – Wait for trigger assertion before executing the next line.
static pack(widths, values)[source]

Pack spline data.

Parameters:
  • widths (list[int]) – Widths of values in multiples of 16 bits.
  • values (list[int]) – Values to pack.
Returns:

Packed data.

Return type:

data (bytes)

host.pdq2.discrete_compensate(c)[source]

Compensate spline coefficients for discrete accumulators.

Given continuous-time b-spline coefficients, this function compensates for the effect of discrete time steps in the target devices.

The compensation is performed in-place.

gateware.pdq2 module

class gateware.pdq2.CRG(platform)[source]

PDQ2 Clock and Reset generator.

Parameters:platform (Platform) – PDQ2 Platform.
rst

Signal – Reset input.

clk_p

Signal – Positive clock output.

clk_n

Signal – Negative clock output.

dcm_sel

Signal – Select doubled clock. Input.

dcm_locked

Signal – DCM locked. Output.

cd_sys

ClockDomain – System clock domain driven.

class gateware.pdq2.Pdq2(platform)[source]

PDQ2 Top module.

Wires up USB FIFO reader gateware.ft245r.Ft345r_rx, clock and reset generator CRG, and the DAC output signals. Delegates the wiring of the remaining modules to Pdq2Base.

pads.go2_out is assigned the DCM locked signal.

Parameters:platform (Platform) – PDQ2 platform.
class gateware.pdq2.Pdq2Base(ctrl_pads, mem_depths=(8192, 8192, 4096))[source]

PDQ2 Base configuration.

Used both in functional simulation and final gateware.

Holds the three gateware.dac.Dac and the communication handler gateware.comm.Comm.

Parameters:
  • ctrl_pads (Record) – Control pads for gateware.comm.Comm.
  • mem_depth (list[int]) – Memory depths for the DAC channels.
dacs

list – List of gateware.dac.Dac.

comm

Modulegateware.comm.Comm.

gateware.comm module

class gateware.comm.Comm(ctrl_pads, dacs)[source]

USB Protocol handler.

Parameters:
  • ctrl_pads (Record) – Control signal pads.
  • dacs (list) – List of gateware.dac.Dac.
sink

Sink[bus_layout] – 8 bit data sink containing both the control sequencences and the data stream.

class gateware.comm.Ctrl(pads, dacs)[source]

Control command handler.

Controls the input and output TTL signals, handled the excaped control commands.

Parameters:
  • pads (Record) – Pads containing the TTL input and output control signals
  • dacs (list) – List of gateware.dac.Dac.
reset

Signal – Reset output from ResetGen. Active high.

dcm_sel

Signal – DCM slock select. Enable clock doubler. Output.

sink

Sink[bus_layout] – 8 bit control data sink. Input.

class gateware.comm.MemWriter(board, dacs)[source]

Handles the memory write protocol and writes data to the channel memories.

Parameters:
  • board (Value) – Address of this board.
  • dacs (list) – List of gateware.dac.Dac.
sink

Sink[mem_layout] – 16 bit data sink.

class gateware.comm.ResetGen(n=128)[source]

Reset generator.

Asserts reset for a given number of cycles when triggered.

Parameters:n (int) – number of cycles.
trigger

Signal – Trigger input.

reset

Signal – Reset output. Active high.

gateware.dac module

class gateware.dac.Dac(fifo=0, **kwargs)[source]

Output module.

Holds the Memory, the Parser, the Sequencer, and its two output line executors.

Parameters:
parser

The memory Parser.

out

The Sequencer and output executor. Connect its data to the DAC.

class gateware.dac.Dds(line, stb, inc)[source]

DDS spline interpolator.

The line data is interpreted as:

  • 16 bit amplitude offset
  • 32 bit amplitude first order derivative
  • 48 bit amplitude second order derivative
  • 48 bit amplitude third order derivative
  • 16 bit phase offset
  • 32 bit frequency word
  • 48 bit chirp
Parameters:
  • line (Record[line_layout]) – Next line to be executed. Input.
  • stb (Signal) – Load data from next line. Input.
  • inc (Signal) – Evolve clock enable. Input.
data

Signal[16] – Output data from this spline.

class gateware.dac.Parser(mem_depth=4096)[source]

Memory parser.

Reads memory controlled by TTL signals, builds lines, and submits them to its output.

Parameters:mem_depth (int) – Memory depth in 16 bit entries.
mem

Memory – Memory to read from.

source

Source[line_layout] – Source of lines read from memory. Output.

arm

Signal – Allow triggers. If disarmed, the next line will not be read. Instead, the Parser will return to the frame address table. Input.

start

Signal – Allow leaving the frame address table. Input.

frame

Signal[3] – Values of the frame selection lines. Input.

class gateware.dac.Sequencer[source]

Line sequencer.

Controls execution of a line. Owns the executors that evolve the line data and sums them together to generate the output. Also manages the line duration counter, the 2**shift counter and the acknowledgment of new line data when the previous is finished.

sink

Sink[line_layout] – Line data sink.

trigger

Signal – Trigger input.

arm

Signal – Arm input.

aux

Signal – TTL AUX (F5) output.

silence

Signal – Silence DAC clocks output.

data

Signal[16] – Output value to be send to the DAC.

class gateware.dac.Volt(line, stb, inc)[source]

DC bias spline interpolator.

The line data is interpreted as a concatenation of:

  • 16 bit amplitude offset
  • 32 bit amplitude first order derivative
  • 48 bit amplitude second order derivative
  • 48 bit amplitude third order derivative
Parameters:
  • line (Record[line_layout]) – Next line to be executed. Input.
  • stb (Signal) – Load data from next line. Input.
  • inc (Signal) – Evolve clock enable. Input.
data

Signal[16] – Output data from this spline.

gateware.platform module

class gateware.platform.Platform[source]

PDQ2 Platform.

  • Xilinx Spartan 3A 500E in a PQ208 package.
  • 50 MHz single ended input clock.
  • Single FT245R USB parallel FIFO.
  • Three 16 bit LVDS DACs.
  • Several TTL control lines.

gateware.cordic module

class gateware.cordic.Cordic(**kwargs)[source]

Four-quadrant CORDIC

Same as TwoQuadrantCordic but with support and convergence for abs(zi) > pi/2 in circular rotate mode or `xi < 0 in circular vector mode.

class gateware.cordic.TwoQuadrantCordic(width=16, widthz=None, stages=None, guard=0, eval_mode='iterative', cordic_mode='rotate', func_mode='circular')[source]

Coordinate rotation digital computer

Trigonometric, and arithmetic functions implemented using additions/subtractions and shifts.

http://eprints.soton.ac.uk/267873/1/tcas1_cordic_review.pdf

http://www.andraka.com/files/crdcsrvy.pdf

http://zatto.free.fr/manual/Volder_CORDIC.pdf

The way the CORDIC is executed is controlled by eval_mode. If “iterative” the stages are iteratively evaluated, one per clock cycle. This mode uses the least amount of registers, but has the lowest throughput and highest latency. If “pipelined” all stages are executed in every clock cycle but separated by registers. This mode has full throughput but uses many registers and has large latency. If “combinatorial”, there are no registers, throughput is maximal and latency is zero. “pipelined” and “combinatorial” use the same number of shifters and adders.

The type of trigonometric/arithmetic function is determined by cordic_mode and func_mode. \(g\) is the gain of the CORDIC.

  • rotate-circular: rotate the vector (xi, yi) by an angle zi. Used to calculate trigonometric functions, sin(), cos(), tan() = sin()/cos(), or to perform polar-to-cartesian coordinate transformation:

    \[ \begin{align}\begin{aligned}x_o = g \cos(z_i) x_i - g \sin(z_i) y_i\\y_o = g \sin(z_i) x_i + g \cos(z_i) y_i\end{aligned}\end{align} \]
  • vector-circular: determine length and angle of the vector (xi, yi). Used to calculate arctan(), sqrt() or to perform cartesian-to-polar transformation:

    \[ \begin{align}\begin{aligned}x_o = g\sqrt{x_i^2 + y_i^2}\\z_o = z_i + \tan^{-1}(y_i/x_i)\end{aligned}\end{align} \]
  • rotate-hyperbolic: hyperbolic functions of zi. Used to calculate hyperbolic functions, sinh, cosh, tanh = cosh/sinh, exp = cosh + sinh:

    \[ \begin{align}\begin{aligned}x_o = g \cosh(z_i) x_i + g \sinh(z_i) y_i\\y_o = g \sinh(z_i) x_i + g \cosh(z_i) z_i\end{aligned}\end{align} \]
  • vector-hyperbolic: natural logarithm ln(), arctanh(), and sqrt(). Use x_i = a + b and y_i = a - b to obtain 2* sqrt(a*b) and ln(a/b)/2:

    \[ \begin{align}\begin{aligned}x_o = g\sqrt{x_i^2 - y_i^2}\\z_o = z_i + \tanh^{-1}(y_i/x_i)\end{aligned}\end{align} \]
  • rotate-linear: multiply and accumulate (not a very good multiplier implementation):

    \[y_o = g(y_i + x_i z_i)\]
  • vector-linear: divide and accumulate:

    \[z_o = g(z_i + y_i/x_i)\]
Parameters:
  • width (int) – Bit width of the input and output signals. Defaults to 16. Input and output signals are signed.
  • widthz (int) – Bit with of zi and zo. Defaults to the width.
  • stages (int or None) – Number of CORDIC incremental rotation stages. Defaults to width + min(1, guard).
  • guard (int or None) – Add guard bits to the intermediate signals. If None, defaults to guard = log2(width) which guarantees accuracy to width bits.
  • eval_mode (str, {"iterative", "pipelined", "combinatorial"}) –
  • cordic_mode (str, {"rotate", "vector"}) –
  • func_mode (str, {"circular", "linear", "hyperbolic"}) – Evaluation and arithmetic mode. See above.
xi, yi, zi

Signal(width), in – Input values, signed.

xo, yo, zo

Signal(width), out – Output values, signed.

new_out

Signal(1), out – Asserted if output values are freshly updated in the current cycle.

new_in

Signal(1), out – Asserted if new input values are being read in the next cycle.

zmax

floatzi and zo normalization factor. Floating point zmax corresponds to 1<<(widthz - 1). x and y are scaled such that floating point 1 corresponds to 1<<(width - 1).

gain

float – Cumulative, intrinsic gain and scaling factor. In circular mode sqrt(xi**2 + yi**2) should be no larger than 2**(width - 1)/gain to prevent overflow. Additionally, in hyperbolic and linear mode, the operation itself can cause overflow.

interval

int – Output interval in clock cycles. Inverse throughput.

latency

int – Input-to-output latency. The result corresponding to the inputs appears at the outputs latency cycles later.

Notes

Each stage i in the CORDIC performs the following operation:

\[ \begin{align}\begin{aligned}x_{i+1} = x_i - m d_i y_i r^{-s_{m,i}},\\y_{i+1} = y_i + d_i x_i r^{-s_{m,i}},\\z_{i+1} = z_i - d_i a_{m,i},\end{aligned}\end{align} \]

where:

  • \(d_i\): clockwise or counterclockwise, determined by sign(z_i) in rotate mode or sign(-y_i) in vector mode.
  • \(r\): radix of the number system (2)
  • \(m\): 1: circular, 0: linear, -1: hyperbolic
  • \(s_{m,i}\): non decreasing integer shift sequence
  • \(a_{m,i}\): elemetary rotation angle: \(a_{m,i} = \tan^{-1}(\sqrt{m} s_{m,i})/\sqrt{m}\).

gateware.escape module

class gateware.escape.Unescaper(layout, escape=165)[source]

Split a data stream into an escaped low bandwidth command stream and an unescaped high bandwidth data stream.

Items in the input stream that are escaped by being prefixed with the escape character, will be directed to the source_b output Source.

Items that are not escaped, and the escaped escape character itself are directed at the source_a output Source.

Parameters:
  • layout (layout) – Stream layout to split.
  • escape (int) – Escape character.
sink

Sink[layout] – Input stream.

source_a

Source[layout] – High bandwidth unescaped data Source.

source_b

Source[layout] – Low bandwidth command Source.

gateware.ft245r module

class gateware.ft245r.Ft245r_rx(pads, clk=10.0)[source]

FTDI FT345R synchronous reader.

Parameters:
  • pads (Record[ft345r_layout]) – Pads to the FT245R.
  • clk (float) – Clock period in ns.
source

Source[bus_layout] – 8 bit data source. Output.

busy

Signal – Data available but not acknowledged by sink. Output.