pyarc2 API Reference

pyarc2.find_ids()

Find all available ArC2 devices. This will return a list with all discovered ids.

>>> from pyarc2 import find_ids
>>> ids = find_ids()
>>> print(ids)
[0, 1]
class pyarc2.ArC2Config(idleMode: IdleMode, controlMode: ControlMode)

Convenience dataclass to group ArC2 configuration options.

exception pyarc2.ArC2Error

Catch-all exception for low-level ArC2 errors. There are five broad categories of low-level errors: (1) FPGA communication errors, (2) Memory access errors (3) Invalid device ID, (4) Inconsistent ramp errors and (5) Output buffer access errors

add_note()

Exception.add_note(note) – add a note to the exception

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class pyarc2.AuxDACFn

Identifier for selecting auxiliary DAC functions. Typically used with pyarc2.Instrument.config_aux_channels().

Variables:
  • SELL – Selector circuit pulls down to this voltage

  • SELH – Selector circuit pulls up to this voltage

  • ARB1 – Arbitrary power supply for DUTs - Max current 100 mA

  • ARB2 – Arbitrary power supply for DUTs - Max current 100 mA

  • ARB3 – Arbitrary power supply for DUTs - Max current 100 mA

  • ARB4 – Arbitrary power supply for DUTs - Max current 100 mA

  • CREF – Reference voltage that the current source sources/sinks current from/to. There should be a ≥3 V headroom between CREF and the expected operating point of the the current source. Must be within 1.5 V of CSET below.

  • CSET – Sets output current of the current source. The difference between CSET and CREF divided by the resistor selected dictates the output current. This should never exceed 1.5 V. Must be within 1.5 V of CREF above.

class pyarc2.BiasOrder

BiasOrder is used in combination with the multi-crosspoint pulse and read operations of ArC2 (pyarc2.Instrument.pulseread_all(), pyarc2.Instrument.pulse_all() and Instrument.read_all()) and marks the order of biasing, either column-wise or row-wise.

Variables:
  • Rows – Bias rows

  • Cols – Bias columns

class pyarc2.ControlMode

ControlMode is used in combination with pyarc2.Instrument.set_control_mode() to switch the daughterboard operation mode. If it’s Header then connections are redirected to the header pins on the daughterboard whereas if Internal then routing will be done internally. The first option is typical when devices are connected to an external interfacing system such as a probe card or manipulator. The latter is typically used with on-board packages.

Variables:
  • Internal – Switch to internal control

  • Header – Switch to external headers

class pyarc2.DataMode

DataMode is used to signify the retrieval mode of values from ArC2 memory. Typically this is used with pyarc2.Instrument.pick_one() or pyarc2.Instrument.get_iter() to read values from memory. If Words/Bits is selected only wordlines/bitlines will be returned. Use All to return all values.

Variables:
  • Words – Return values associated with wordlines

  • Bits – Return values associated with bitlines

  • All – Return all data

class pyarc2.IdleMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

IdleMode is used with Instrument.finalise_operation() to mark at what state the channels should be left. Selecting Float will disconnect all channels and leave their state unchanged. SoftGnd will reset all channels to arbitrary voltage operation and set them to 0.0 V. HardGnd will disconnect all channels from the DACs and connect them to hard ground.

Float: int = 1

Float Channels

HardGnd: int = 3

Tie channels to GND

SoftGnd: int = 2

Tie channels to 0 V

class pyarc2.Instrument(port: int, firmware: str)

To do anything with ArC TWO you will need first to instantiate an Instrument. The constructor requires a port number and a path to load fimrware from. Using find_ids() will return all available ArC TWO instrument ports.

>>> from pyarc2 import Instrument, find_ids
>>> ids = find_ids()
>>> if len(ids) == 0:  # no instruments ound
>>>     return
>>> # Connect to the first available ArC TWO loading firmware "fw.bin"
>>> arc = Instrument(ids[0], 'fw.bin')
Parameters:
  • port (int) – The EFM id of the ArC TWO to connect to

  • firwmare (str) – Path of the firmware to load

Returns:

A new instance of pyarc2.Instrument

bit_currents_from_address(addr, /)

Read all bit current values from specific address segment. This will return all bit-related values stored in the segment in ascending channel order

Parameters:

addr (int) – The memory address to read currents from

Returns:

An array with the currents of all bitline-corresponding channels

Return type:

A numpy f32 array

busy()

Returns True if the command buffer has not been consumed.

config_aux_channels(config, base, /)

Configure the ArC2 auxiliary DACs. The AUX DACs manage signals required by the peripheral ArC2 circuitry. The only argument is an array of tuples containing a list of AUX DAC functions (tuple item #0) to set at specified voltage (tuple item #1). The available functions are specified by AuxDACFn.

Parameters:

voltages – An array of tuples [(aux dac fn, voltage), ...]

config_channels(config, base, /)

Configure a set of channels at specific voltages.

Parameters:
  • config – An array of tuples [(channel, voltage), ...] specifying the voltage configuration.

  • base – Voltage to set all channel not included in config. Set to None to leave them at their current state.

config_selectors(selectors, /)

Configure the ArC2 selector circuits. The array is a list of selector channels (0..31) to toggle high. The rest of the selectors will be toggled low. This function does not configure the voltage of the low and high levels, as this must be done with config_aux_channels() and setting the high and low voltages through the AuxDACFn SELH/SELL variables. Perhaps unintuitively the high voltage can actually be configured to be lower than low although the usefulness of this choice is questionable.

>>> # the following will set the low and high voltage for selectors to
>>> # 0.0 and 3.3 V respectively and toggle selectors 9 and 12 to high.
>>> arc2.config_aux_channels([(AuxDACFn.SELL, 0.0), (AuxDACFn.SELH, 3.3)])
>>>     .config_selectors([9, 12])
>>>     .execute()

Voltage configuration need only be provided once as it is sticky.

Parameters:

selectors – An array of selectors to toggle high. Use an empty array to clear all selectors

connect_to_gnd(chans: Iterable[int] | ndarray) Instrument

Modify previously configured channels by switching them to ground. Use an empty array to clear.

Parameters:

chans – The channels to ground; this must be a numpy uint64 array or any Iterable whose elements can be converted to uint64.

currents_from_address(addr: int, chans: Iterable[int] | ndarray) ndarray

Read current values from specific address segment. This will return all the channel values stored in the segment in ascending channel order

Parameters:
  • addr (int) – The memory address to read currents from

  • chans – The channel numbers to retrieve values from. This must be a numpy uint64 array or any Iterable whose elements can be converted to uint64.

Returns:

An array with the currents of selected channels; unselected channels will be replaced with Nan

Return type:

A numpy f32 array

delay(nanos, /)

Insert a delay of nanos nanoseconds in the command buffer.

execute()

Write everything in the command buffer to the instrument. This will cause ArC2 to start executing the instructions provided.

finalise_operation(mode: IdleMode | None = None, control: ControlMode | None = None)

This function is used to safely reset channels and daughterboard control at the end of an operation. The available options are outlined in IdleMode and ControlMode. Please note that floating the channels will disconnect them and leave them in the configuration they were before. For instance at the end of a fast operation (fast pulses, fast ramps, etc) the channels will still be left in a High Speed driver mode. However explicitly grounding the devices will switch them to arbitrary voltage (incurring the 120 μs penalty to do so). Setting any of the two arguments as None will retain existing configuration.

Parameters:
float_all()

Disconnect all channels.

generate_ramp(low, high, vstart, vstep, vstop, pw, inter, npulse, readat, readafter, /)

Initiate a ramp operation in ArC2. This will spawn a background process that bias the selected low and high channels based on the parameters specified. Please note that results must be retrieved from ArC2 using the get_iter() method which iterates and expends the internal output buffer. Alternatively pick_one() will return the first available result.

Parameters:
  • low (int) – The low voltage channel (typ. grounded)

  • high (int) – The high voltage channel

  • vstart (float) – The initial voltage of the ramp

  • vstep (float) – The increment (or decrement) of every ramp step

  • vstop (float) – The final voltage step

  • pw_nanos (int) – The pulse width for each individual pulse in nanoseconds

  • inter_nanos (int) – Delay between consecutive pulses in nanoseconds

  • num_pulses (int) – Number of pulses per individual voltage step

  • read_at – Variant of pyarc2.ReadAt denoting the voltage (if any) of read-out operations (if any)

  • read_after – Variant of pyarc2.ReadAfter denoting when read-outs will be done (if ever)

generate_read_train(lows: Iterable[int] | ndarray | None, highs: Iterable[int] | ndarray, vread: float, nreads: int, inter_nanos: int, ground: bool) Instrument

Initiate a current read train. This will queue instructions that will read currents between lows and highs channels. The low channels can be None which means that ArC 2 will do open reads from the high channels. Results must be retrieved with an iterator as described in generate_ramp().

Parameters:
  • lows – An array of unsinged integers denoting the low channels or None for unbiased open reads

  • highs – An array of unsigned integeres denoting the channels to read current from

  • vread (float) – Read-out voltage

  • nreads (int) – Number of current reads to perform

  • inter_nanos (int) – Delay (in ns) between subsequent reads; can be 0

  • ground (bool) – Whether to ground high and low channels after the operation

generate_vread_train(chans: Iterable[int] | ndarray, averaging: bool, npulses: int, inter_nanos: int) Instrument

Initiate a voltage read train. This will queue instructions that will read voltages from all uchans channels. Results must be retrieved with an iterator as described in generate_ramp().

Parameters:
  • uchans – An array of unsinged integers to read voltages from

  • averaging (bool) – Whether to perform averaged (True) or one-shot reads (False).

get_iter(mode: DataMode, rtype: ReadType | None = None)

Return an iteration on the internal data buffer. This allows users to iterate through the saved results on ArC2’s memory in the order they were saved. The available modes of retrieval are outlined in pyarc2.DataMode.

>>> from pyarc2 import Instrument, ReadAt, ReadAfter, DataMode, IdleMode
>>> arc = Instrument(0, '/path/to/firmware')
>>> arc.generate_ramp(3, 3, 0.0, 0.1, 1.0, 1e-7, 10e-6, 5, ReadAt.Bias, ReadAfter.Pulse)
>>>    .execute()
>>>    .finalise_operation(IdleMode.Gnd)
>>>    .wait()
>>> data = arc.get_iter(DataMode.Bits)
>>> for datum in data:
>>>     print(datum) # 32-element array containing bitline currents
Parameters:

mode – A variant of pyarc2.DataMode

Returns:

An iterator on the internal data buffer

ground_all()

Ground all channels and revert them to arbitrary voltage operation.

ground_all_fast()

Ground all channels maintaing current channel operating mode.

open_channels(channels, /)

Set selected channels to open, disconnecting them from the DACs. This alone is not enough to float a channel because it might be grounded previously. To properly float a channel you will have to disconnect the channels from ground first. This example floats all channels properly.

>>> arc.connect_to_gnd([])  # clear grounds
>>>    .open_channels(list(range(64))) # set channels to open
>>>    .execute()
Parameters:

channels – An array of uint64s or any Iterable with elements that can be converted into uint64

pick_one(mode, /)

Read a slab of data from the internal long operation buffer. This clears the memory area after reading.

Parameters:
  • mode – A variant of pyarc2.DataMode.

  • rtype – A variant of pyarc2.ReadType. Use Current to decode values into current readings or Voltage to decode them into voltage readings

Returns:

An array with 64 (if DataMode.All) or 32 (for any other DataMode variant) floats

Return type:

An f32 numpy array

pulse_all(voltage, nanos, order, /)

Pulse all crosspoints in the array, by biasing either rows or columns.

Parameters:
  • voltage (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • order – A variant of pyarc2.BiasOrder

pulse_one(low, high, voltage, nanos, /)

Apply a pulse between the specified crosspoints with specified voltage and pulse width (in nanoseconds).

Parameters:
  • low (int) – The low voltage channel (typ. grounded)

  • high (int) – The high voltage channel

  • voltage (float) – The pulsing voltage

  • nanos (int) – The duration of the pulse in nanoseconds

pulse_slice(chan, voltage, nanos, /)

Apply a pulse to a row or column using chan as the low channel with specified voltage and pulse width (in nanoseconds).

Parameters:
  • chan (int) – The low voltage channel (typ. grounded)

  • voltage (float) – The pulsing voltage

  • nanos (int) – The duration of the pulse in nanoseconds

pulse_slice_fast_open(chans, timings, preset_state, /)

Apply a sub-500 ms pulse to all specified channels. This differs from pulse_slice() as it does not expect a low potential channel as the “receiving” end. When preset_state is true the state of high speed drivers will be initialised before the actual pulsing sequence begins. chans is a list of tuples - [(chan number, pulse voltage, normal voltage), ...] - and cl_nanos contains the timings per cluster. cl_nanos MUST be 8-items long or a ValueError will be raised. A cluster timing can be None which means that the channels of this cluster won’t be pulsed at all. This method will throw an error if a channel is included in the chans list but the channel’s corresponding cluster timing, int(chan/8), is set to None.

Be aware that the transition of voltages on channels belonging to the same cluster must be identical, which effectively means that there can be only one type of transition from pulse voltage to normal voltage per 8 consecutive channels (so high → low or low → high). If mixed transitions are provided an error will be raised.

Also note that this function uses only the high speed drivers of ArC2 for pulse generation. As such the maximum pulse width is limited to 500 ms. If you want longer pulses you can get the same behaviour with a chain of config_channels() and delay() instructions.

Parameters:
  • chans (list) – A list of triples containing the configuration of the selected channels in the form (chan number, pulse voltage, normal voltage)

  • cl_nanos (list) – A list of 8 values containing the cluster timings (pulse widths) in nanoseconds - can be None which will effectively skip the cluster altogether

  • preset_state (bool) – Whether the high speed drivers should be preloaded before the actual pulsing

Raises:
  • ValueError – When the timings list contains more or fewer than 8 elements

  • ArC2Error – When incorrect timings or incompatible channel polarities are supplied.

pulse_slice_masked(chan: int, voltage: float, nanos: int, mask: Iterable[int] | ndarray) Instrument

Apply a pulse to a row or column using chan as the low channel with specified voltage and pulse width (in nanoseconds) and also limit the high channels to those specified by the mask array.

Parameters:
  • chan (int) – The low voltage channel

  • voltage (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • mask – A numpy array or Iterable with the high voltage channels; same semantics as read_slice_masked()

pulseread_all(vpulse, nanos, vread, order, /)

Pulse and read all the crosspoints. Same semantics as pulse_all() and read_all() apply.

Parameters:
  • vpulse (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • vread (float) – The read-out voltage

  • order – A variant of pyarc2.BiasOrder denoting which rows are biased during read-out.

Returns:

An 32×32 array containing the current measured on each individual cronsspoint

Return type:

A numpy (2, 2) f32 ndarray

pulseread_one(low, high, vpulse, nanos, vread, /)

Pulse and then read a crosspoint. Same semantics as pulse_one and read_one apply.

Parameters:
  • low (int) – The low voltage channel

  • high (int) – The high voltage channel

  • vpulse (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • vread (float) – The voltage to read at after pulsing

Returns:

The current between the specified crosspoints at vread after a vpulse pulse of nanos duration has been applied

Return type:

float

pulseread_slice(chan, vpulse, nanos, vread, /)

Pulse and then read a row/column. Same semantics as pulse_slice() and read_slice() apply.

Parameters:
  • chan (int) – The low voltage channel

  • vpulse (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • vread (float) – The voltage to read at

Returns:

The current of each individual channel along the chan line sinked at chan after a vpulse pulse of nanos duration has been applied

Return type:

A numpy f32 array

pulseread_slice_masked(chan: int, mask: Iterable[int] | ndarray, vpulse: float, nanos: int, vread: float) ndarray

Pulse and read specified high channels that have chan as low potential channel. Same semantics as pulse_slice_masked() and read_slice_masked() apply.

Parameters:
  • chan (int) – The low voltage channel

  • mask – A numpy array or Iterable with the high-voltage channels. Elements must be uint64 or convertible to uint64

  • vpulse (float) – The pulsing voltage

  • nanos (int) – The pulse duration in nanoseconds

  • vread (float) – The voltage to read at

Returns:

The current of each selected channel along the chan line sinked at chan; unselected channels will default to NaN

Return type:

A numpy f32 array

read_all(vread, order, /)

Read all the available crosspoints at the specified voltage. This can be done by biasing either rows or columns.

Parameters:
  • vread (float) – The read-out voltage

  • order – A variant of pyarc2.BiasOrder denoting which rows are biased during read-out.

Returns:

An 32×32 array containing the current measured on each individual cronsspoint

Return type:

A numpy (2, 2) f32 ndarray

read_one(low, high, vread, /)

Perform a current read between the specified channels. The low channel will be biased with -vread and the current will be read from the high channel.

Parameters:
  • low (int) – The low voltage channel

  • high (int) – The high voltage channel

  • vread (float) – The voltage to read at

Returns:

The current between the specified crosspoints at vread

Return type:

float

read_slice(chan, vread, /)

Read all the values which have chan as the low channel. If chan is between 0 and 15 or 32 and 47 (inclusive) this will correspond to a row read at vread in a standard 32×32 array. Otherwise it’s a column read.

Parameters:
  • chan (int) – The low voltage channel

  • vread (float) – The voltage to read at

Returns:

The current of each individual channel along the chan line sinked at chan

Return type:

A numpy f32 array

read_slice_masked(chan: int, mask: Iterable[int] | ndarray, vread: float) ndarray

Read all the masked high channels which have chan as the low channel. If chan is between 0 and 15 or 32 and 47 (inclusive) this will correspond to a row read at vread in a standard 32×32 array. Otherwise it’s a column read.

Parameters:
  • chan (int) – The low voltage channel

  • mask – The high-voltage channels. This must be a numpy uint64 array or any other Iterable whose elements can be converted to uint64

  • vread (float) – The voltage to read at

Returns:

The current of each selected channel along the chan line sinked at chan; unselected channels will default to NaN

Return type:

A numpy f32 array

read_slice_open(highs: Iterable[int] | ndarray, ground_after: bool) ndarray

Perform an open current measurement along the specified channels. This method does not do any bias-related setup. It’s up to the user to setup channels before performing the read. If ground_after is True or None a ground operation will additionally be issued post-read.

Parameters:
  • highs – The channels to read currents from. This must be a numpy uint64 or an Iterable whose elements can be converted to uint64

  • ground_after (bool) – Whether channels will be grounded automatically after current is read

Return type:

A numpy f32 array

read_train(low, high, vread, interpulse, condition, /)

Perform a retention-like operation based on subsequent number of read pulses which can be separated by interpulse nanoseconds.

Parameters:
  • low (int) – The low voltage channel (typ. grounded)

  • high (int) – The high voltage channel

  • vread (float) – Read-out voltage

  • interpulse (int) – Delay between consecutive read-outs in nanoseconds

  • condition – Variant of pyarc2.WaitFor denoting the termination condition for this read train

set_control_mode(mode, /)

Set daughterboard control mode either as Internal or Header

Parameters:

mode – A variant of pyarc2.ControlMode

set_logic(channel_mask, enable, /)

Set the digital I/Os specified by mask to either high (when enable is True) or low (when enable is False). An execute() is required to actually load the configuration.

Parameters:

mask (int) – A u32 bitmask of the channels this function will be applied to

vread_channels(chans: Iterable[int] | ndarray, averaging: bool) List[float]

Do a voltage read across selected channels.

Parameters:
  • chans – A uint64 numpy array or Iterable of the channels to read voltage from

  • averaging (bool) – Whether averaging should be used

Return type:

An array with the voltage readings of the selected channels in ascending order

wait()

Block until the instrument has executed its command buffer.

word_currents_from_address(addr, channels, /)

Read all word current values from specific address segment. This will return all word-related values stored in the segment in ascending channel order

Parameters:

addr (int) – The memory address to read currents from

Returns:

An array with the currents of all wordline-corresponding channels

Return type:

A numpy f32 array

class pyarc2.ReadAfter

ReadAfter is used with ramp operations of ArC2 (pyarc2.Instrument.generate_ramp()) and it signifies at when should read-outs be done. This can be either after a biasing pulse (Pulse), after a block of biasing pulses (if more that one, Block), at the end of the Ramp (Ramp) or never (Never). The last option also implies ReadAt.Never.

Variables:
  • Pulse – Read after pulsing

  • Ramp – Read at the end of a ramp

  • Block – Read after a block of indentical pulses

  • Never – Never read

static from_str(r, /)

Generate a ReadAfter object from a string value.

Parameters:

r (str) – One of pulse, ramp, block, never

Returns:

A new ReadAfter directive

Raises:

ValueError – If a different value is provided

class pyarc2.ReadAt

ReadAt is used with ramp operations of ArC2 (pyarc2.Instrument.generate_ramp()) and it signifies at what voltage should read-outs be done when requested. This can be either at Bias (current ramp voltage), arbitrary voltage pyarc2.ReadAt.Arb() or Never if no read-outs are requested. The latter also implies ReadAfter.Never.

Variables:
  • Bias – Read at current bias

  • Never – Never read

  • Arb – Read at arbitraty voltage - see Arb()

static Arb(self, voltage, /)

Do read-outs at arbitrary voltage.

Parameters:

voltage (f32) – The value of the arbitrary voltage

Returns:

A new ReadAt directive

voltage()

Get the current voltage for this operation if this object was created with pyarc2.ReadAt.Arb(). It will raise an exception otherwise.

Returns:

The voltage associated with this directive

class pyarc2.WaitFor

Wait condition for long running operations, such as pyarc2.Instrument.read_train().

static Iterations()

Wait a specified number of iterations

Parameters:

nanos (int) – The number of iterations to wait

Returns:

A new WaitFor directive

static Millis()

Wait a specified number of milliseconds

Parameters:

millis (int) – The number of milliseconds to wait

Returns:

A new WaitFor directive

static Nanos()

Wait a specified number of nanoseconds

Parameters:

nanos (int) – The number of nanoseconds to wait

Returns:

A new WaitFor directive