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 ofCSET
below.CSET – Sets output current of the current source. The difference between
CSET
andCREF
divided by the resistor selected dictates the output current. This should never exceed 1.5 V. Must be within 1.5 V ofCREF
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()
andInstrument.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’sHeader
then connections are redirected to the header pins on the daughterboard whereas ifInternal
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()
orpyarc2.Instrument.get_iter()
to read values from memory. IfWords
/Bits
is selected only wordlines/bitlines will be returned. UseAll
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. SelectingFloat
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. Usingfind_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 toNone
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 theAuxDACFn
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
andControlMode
. 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 asNone
will retain existing configuration.- Parameters:
mode – A variant of
IdleMode
control – A variant of
ControlMode
- 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
andhigh
channels based on the parameters specified. Please note that results must be retrieved from ArC2 using theget_iter()
method which iterates and expends the internal output buffer. Alternativelypick_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
andhighs
channels. The low channels can beNone
which means that ArC 2 will do open reads from the high channels. Results must be retrieved with an iterator as described ingenerate_ramp()
.- Parameters:
lows – An array of unsinged integers denoting the low channels or
None
for unbiased open readshighs – 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 ingenerate_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 otherDataMode
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. Whenpreset_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), ...]
- andcl_nanos
contains the timings per cluster.cl_nanos
MUST be 8-items long or aValueError
will be raised. A cluster timing can beNone
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 thechans
list but the channel’s corresponding cluster timing,int(chan/8)
, is set toNone
.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()
anddelay()
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 altogetherpreset_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()
andread_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
andread_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 avpulse
pulse ofnanos
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()
andread_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 atchan
after avpulse
pulse ofnanos
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 aspulse_slice_masked()
andread_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 atchan
; unselected channels will default toNaN
- 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. Ifchan
is between 0 and 15 or 32 and 47 (inclusive) this will correspond to a row read atvread
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 atchan
- 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. Ifchan
is between 0 and 15 or 32 and 47 (inclusive) this will correspond to a row read atvread
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 atchan
; unselected channels will default toNaN
- 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 (whenenable
isTrue
) or low (whenenable
isFalse
). Anexecute()
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 impliesReadAt.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 atBias
(current ramp voltage), arbitrary voltagepyarc2.ReadAt.Arb()
orNever
if no read-outs are requested. The latter also impliesReadAfter.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