Pattern generator
This chapter focuses on the functions and notions related to the building of logic patterns with SP1000G series devices.
To use a pattern generator script with an SP1000G series device, one must follow those steps:
- Add your script in
Pattern Generatorsection, - Then, you have to click on
Start Generate and Capture, ScanaStudioexecutes the script that builds the pattern, sends pattern data to the SP1000G device, which will generate the pattern and capture logic signals while generating.
A simple pattern generator script will carry the main tasks below:
- Build a pattern, defining the logic levels and sequences on all channels of interest
- define the number of time the pattern must be repeated
- send the pattern to the device and start generation
- wait for pattern generation de be done.
As you will discover in this chapter, pattern generator scripts may get more sophisticated if this is needed to achieve required goals (e.g. generating long patterns)
Signal generation functions​
To generate patterns with SP1000G device, one have two options:
- Use the legacy signal builder functions. (not recommended for SP1000G pattern generation), those functions are
builder_add_samples(),builder_add_cycle()andbuilder_add_cycles()and are detailed in the signal builder chapter. - Use dedicated pattern generator functions that extends the capabilities of the SP1000G pattern generation (recommended method).
The latter (dedicated pattern generator functions) are described in detail later in this chapter. These dedicated functions are particularly aimed at application that need to generate test pattern, like *.STILL files, *.WGL file, *.VCD file or other vendor specific formats. One of the most common use of that mode is for semiconductor testing ATE systems. That being said, it can be adapted to any
signal builder functions used within SP1000G pattern generation context are deprecated as of January 2025. We recommend only using dedicated pattern generator functions found in that document when working with SP1000G devices.
Chunk memory structure​
While SP1000G can stream captured data to the host computer, it is not able to stream data the other way around, from the host computer to the device. In order to generate logic signals, first the data need to be transferred from the host computer to the device's internal memory.
A chunk is defined in this context as a certain amount of logic transitions that are loaded into SP1000G's internal memory and can be generated once, a predetermined number of times, or in an infinite loop (until the STOP button is pressed in ScanaStudio).
A chunk has a maximum size, thus, if the amound of data that needs to be generated exceeds that maximum size, it needs to be splitted into several chunks.
There is no need to completely fill a chunk before starting another chunk. However, the generation of a previous chunk needs to be done before a new chunk can be loaded. That also means that there will always be a non-deterministic delay between two chunks.
It's important to understant the way generator data may be split into chunks to be able to design the generated script in a way that makes the most out of each chunk and alleviates any limitations that may be caused by this.
Entry point functions​
If you want to write a script which is able to build and generate logic pattern with an SP1000G series device, your script must have these three entry point functions defined.
function on_draw_gui_pattern_generator()
{
// Function called when ScanaStudio needs to display the GUI
}
function on_eval_gui_pattern_generator()
{
// Function to evaluate (and validate) the choices set by the user in the GUI
}
function on_pattern_generate()
{
// Function to build the signals you want to generate
}
Function on_draw_gui_pattern_generator()​
Description : This entry point function is launched when you add the script in Pattern Generator section. It will display a GUI, an interface which can be used (for example) :
- To configure parameters you want to take into account for the signals generation (like letting the user configure which channels on which the signals should be generated).
- To show information to user.
This entry point function is optional ; you don't have to write between the braces if you don't need it.
Context : Pattern generator
Function on_eval_gui_pattern_generator()​
Description : This entry point function is used to evaluate if the GUI configuration (the choices made by the user in the GUI) is valid. The approach is often to:
- Retrieve the values entered by the user in the GUI,
- Test if this value is valid,
- Then a display of an error message if this value doesn't correspond to criteria you defined.
This entry point function is optional.
Context : Pattern generator
Entry point function on_pattern_generate()​
Description : This is the entry point function which is called when the user clicks on "start capture and generate". It's purpose should be the build the logic pattern, load it into the device and start generation.
Context : Pattern generator
Configuring channels​
The probes are set up with the builder_probe_* functions, on every SP1000G probe model. Each channel used as a generator also has an idle state, set with builder_set_idle_state().
Every channels argument is a channel index (0-based) or an array of channel indexes.
| Function | What it does |
|---|---|
builder_probe_set_io(channels, io_type) | Drive mode: ScanaStudio.io_type.push_pull, .open_drain_no_pull, .open_drain_pull_up or .float (released, the target drives the line). |
builder_probe_set_voh(channels, mv) | High level, in mV (10 mV steps). |
builder_probe_set_vol(channels, mv) | Low level, in mV (P992 only). |
builder_probe_set_voh_tracking(channels, on) | P992 only. With on true, the channel's high level follows the target's supply, as the probe measures it on its VT input. With false, it returns to its set VOH. |
builder_probe_apply() | Applies every change staged since the previous apply, all at once. |
ScanaStudio.builder_probe_set_io([0, 1], ScanaStudio.io_type.push_pull); // drive mode
ScanaStudio.builder_probe_set_voh([0, 1], 3300); // high level, mV
ScanaStudio.builder_set_idle_state(0, 1); // idle state of CH1
ScanaStudio.builder_set_idle_state(1, 0); // idle state of CH2
If you are not sure which drive mode to use:
- Push-pull suits interfaces with single-direction lines (e.g. SPI, UART).
- Open drain suits bidirectional single-line interfaces where more than two devices share the line (e.g. I2C, One-Wire).
- Float releases the line so that the target can drive it, for example while it answers.
How a set-up change takes effect​
-
Before the chunk's first step: a call sets the configuration the chunk starts with. The device is set up before the pattern plays, so the pattern starts on time, triggered or not.
builder_probe_apply()is not needed here. -
After a step: a call stages a change at that point of the pattern.
builder_probe_apply()applies all staged changes at once.- The generator holds its current levels while the device reconfigures the probes, then continues with the next step by itself.
- This also works inside
builder_loop_start()/builder_loop_end(), applying on every pass.
-
How long an apply holds the pattern:
P992 P990 P991 Drive-mode change about 3 ms about 6 ms about 7 ms VOH raised on a driving channel about 55 ms about 10 ms about 10 ms VOH lowered on a driving channel about 55 ms about 155 ms (the level comes down slowly) about 10 ms VOL changed about 55 ms — — -
VOH tracking (P992):
- Like the other calls, before the chunk's first step it is part of the configuration the chunk starts with: the high level already follows the target when the pattern starts. After a step, it is staged and needs
builder_probe_apply(). - While a channel tracks, its high level follows the target's supply as it changes, within a few hundredths of a second.
- With no target supply on VT (under about 0.8 V), the channel drives its set VOH instead.
- Connect the probe's VT input to the target's supply for it to work.
- Like the other calls, before the chunk's first step it is part of the configuration the chunk starts with: the high level already follows the target when the pattern starts. After a step, it is staged and needs
-
Chunks: each chunk starts from the configuration the previous one ended with. A change made after a chunk's last step therefore applies from the next chunk's start.
-
Sample-based patterns (
builder_add_samples(),builder_add_cycle(),builder_add_cycles()): thebuilder_probe_*calls set the chunk's starting configuration.builder_probe_apply()does nothing there. -
When a probe can't do what is asked: the script keeps running and the console says what was adjusted (see What each probe supports).
Example: a pulse on CH1, then CH1 is released for the target to answer, then driven again, 100 times.
function on_pattern_generate()
{
var hi = [1], lo = [0];
for (var ch = 1; ch < 9; ch++) { hi.push(0); lo.push(0); }
// starting configuration: set before the pattern plays
ScanaStudio.builder_probe_set_io(0, ScanaStudio.io_type.push_pull);
ScanaStudio.builder_probe_set_voh(0, 3300);
ScanaStudio.builder_loop_start(100);
// drive a pulse on CH1
ScanaStudio.builder_add_step(hi, 125); // 1 us
ScanaStudio.builder_add_step(lo, 125);
// release CH1 for the target to answer
ScanaStudio.builder_probe_set_io(0, ScanaStudio.io_type.float);
ScanaStudio.builder_probe_apply();
ScanaStudio.builder_add_step(lo, 12500); // 100 us
// take it back, push-pull
ScanaStudio.builder_probe_set_io(0, ScanaStudio.io_type.push_pull);
ScanaStudio.builder_probe_apply();
ScanaStudio.builder_loop_end();
ScanaStudio.builder_start_chunk();
ScanaStudio.builder_wait_done();
}
Firmware​
ScanaStudio offers the device firmware update when a script needs it.
- A P992 changing set-up mid-pattern needs controller 0.19 and core 0x1B.
- A P990 or P991 changing set-up mid-pattern, or a P992 starting with different levels per channel, needs controller 0.21.
- VOH tracking on a P992 (from the chunk's start or mid-pattern) needs controller 0.21.306 (firmware package 2026-11-06.4).
With older firmware, a script that needs it stops with a message asking to update. Scripts that only set the probes up before the first step run on any firmware.
What each probe supports​
| P992 | P990 | P991 | |
|---|---|---|---|
| Drive mode | per channel | per channel | per channel |
| High level (VOH) | per channel | one for the 9 channels of the probe; the last value set wins | same as P990 |
| VOH range | 0 V to 5 V | 1.8 V to 3.29 V | 1.65 V to 5 V |
| Low level (VOL) | per channel | 0 V, not adjustable | 0 V, not adjustable |
| VOH tracking | per channel, follows the supply measured on VT | no (warning, VOH kept) | no (warning, VOH kept) |
| Open drain without pull-up | yes | keeps its pull-up | keeps its pull-up |
float | no pull | pull-down | pull-down |
A value out of a probe's range is brought into it, with a console warning.
ScanaStudio.builder_set_out_voltage(channel_index, voltage_in_mV)​
Deprecated. Alias of builder_probe_set_voh(channel, mV). Existing scripts keep working; new scripts should use builder_probe_set_voh(). A script that calls it prints a deprecation warning in the script console.
One difference: when called after a step, the change is applied automatically before the next step (no builder_probe_apply() needed).
Context : Pattern generator
ScanaStudio.builder_set_idle_state(channel_index, idle_state)​
Description : The idle state for a channel is the logic level (1 our 0) that will be set for an output-configured channel before the chunk is started, in between two chunks, or after the last chunk generation is done.
Parameters :
- channel_index : Index of the channel (0 Based, that is the first channel's index in 0).
- idle_state : This value depends on your use, and is either 0 or 1.
Example :
If you want to initialize the idle state of the first channel to 1, you can write :
ScanaStudio.builder_set_idle_state(0, 1) ;
Context : Pattern generator
ScanaStudio.builder_set_io(channel_index, output_type)​
Deprecated. Alias of builder_probe_set_io(channel, io_type). Existing scripts keep working; new scripts should use builder_probe_set_io(). A script that calls it prints a deprecation warning in the script console.
One difference: when called after a step, the change is applied automatically before the next step (no builder_probe_apply() needed).
Context : Pattern generator
Dedicated pattern generation functions​
The functions below are used to describe the signals to be physically generated on the probes. In other words, they are used to fill the chunks with the pattern to be generated, and the control the generation of that chunk by inserting loops or pauses.
it's not possible to mix the functions below and the legacy signal builder functions (builder_add_samples(), builder_add_cycle() and builder_add_cycles()) in a same script execution.
ScanaStudio.builder_add_step(channel_data[], hold)​
Description : Adds a logic level on all channels, for a duration of hold samples.
Parameters :
- channel_data[] : An array of integers (0 or 1), have the same size as the number of channels of the device being used. This array describe the logic level on all channels. Only channels configured as output-capable will be affected.
- hold : An integer describing the number of samples to hold the logic level described by
channel_data[]
Example :
var ch_val = [];
for (var ch = 0; ch < ScanaStudio.get_device_channels_count(); ch++) {
ch_val.push(1);
}
ScanaStudio.builder_add_step(ch_val, 100); //Adds 100 samples
Context : Pattern generator
ScanaStudio.builder_loop_start(quint32 loop_count)​
Description : This function allows a part of the pattern to be repeated for loop_count times. The part of the pattern to be repeated should be delimited by builder_loop_start() and builder_loop_end(). Please note that only 3 nested loop levels are allowed.
Parameters :
- loop_count : The number of times the loop should be repeated. 0 means infinite loop. Maximum value should fit on 28 bits integer.
Example :
var ch_val = [];
for (var ch = 0; ch < ScanaStudio.get_device_channels_count(); ch++) {
ch_val.push(1);
}
ScanaStudio.builder_add_step(ch_val, 100); //Adds 100 samples
ScanaStudio.builder_loop_start(100);
ch_val[0] = 0;
ScanaStudio.builder_add_step(ch_val, 100);
ch_val[0] = 1;
ScanaStudio.builder_add_step(ch_val, 200);
ch_val[0] = 0;
ScanaStudio.builder_add_step(ch_val, 300);
ScanaStudio.builder_loop_end();
Context : Pattern generator
ScanaStudio.builder_loop_end()​
Description : Used in conjunction with builder_loop_start() to repeat a parts of the pattern.
Context : Pattern generator
ScanaStudio.builder_get_loop_level()​
Description : returns the current loop level (in case of several nested loops). 3 is the top level, meaning no any loop is currently "open". Returning 2 means currently one loop is started with builder_loop_start(), 1 means two nested loops are started, 0 means three nested loops are started an no more loops can be started before close one or more open loops with builder_loop_end().
Context : Pattern generator
ScanaStudio.builder_get_max_chunk_size()​
Description : This function returns the maximum number of transitions that can be stored in a chunk. The maximum chunk size depends on hardware embedded memroy and device firmware version.
Context : Pattern generator
Controlling pattern generation​
ScanaStudio.builder_start_chunk()​
Description : This function sends a chunk to your device's memory and starts generating it. Please note, however, that if "wait for trigger" option box is ticked in ScanaStudio's GUI, in the Pattern Generator panel, then the first chuck will not start generating until the device trigger condition occurs.
Context : Pattern generator
ScanaStudio.builder_add_pause()​
Description : Request the pattern to be paused, keeping all signals unchanged until resumed by the user
Example :
var ch_val = [];
for (var ch = 0; ch < ScanaStudio.get_device_channels_count(); ch++) {
ch_val.push(1);
}
ScanaStudio.builder_add_step(ch_val, 100); //Adds 100 samples
ch_val[0] = 0;
ScanaStudio.builder_add_step(ch_val, 100);
ScanaStudio.builder_add_pause() // <------ Pattern will pause here until resumed by the user.
ch_val[0] = 1;
ScanaStudio.builder_add_step(ch_val, 200);
ch_val[0] = 0;
ScanaStudio.builder_add_step(ch_val, 300);
Context : Pattern generator
ScanaStudio.builder_probe_apply()​
Description : Applies, at this point of the pattern, every probe set-up change staged with the builder_probe_* functions since the previous apply, all at once. The generator holds its current levels while the device reconfigures the probes, then continues with the next step. Inside a loop, the changes are applied on every pass.
Before the chunk's first step, the builder_probe_* calls set the configuration the chunk starts with, and builder_probe_apply() is not needed. See How a set-up change takes effect.
Example :
ScanaStudio.builder_add_step(ch_val, 100);
// release CH1 and set CH2 high level to 1.8 V, then continue
ScanaStudio.builder_probe_set_io(0, ScanaStudio.io_type.float);
ScanaStudio.builder_probe_set_voh(1, 1800);
ScanaStudio.builder_probe_apply();
ScanaStudio.builder_add_step(ch_val, 100);
Context : Pattern generator
ScanaStudio.builder_wait_done(timeout_ms)​
Description : Once the chunk is sent using ScanaStudio.builder_start_chunk(), calling this function will return true or false, depending on whether or not the device has finished generating the chunk that is loaded in memory. It's important to wait for the device to return true before sending starting another chunk.
Note : Although it's not legal to start a new chunk while the previous one is still being generated, it's totally legal (and even considered good practice) to start building the next chunks right after calling ScanaStudio.builder_start_chunk(). Only the next call to ScanaStudio.builder_start_chunk() need to be delayed until ScanaStudio.builder_wait_done() return true
Parameters :
- timeout_ms : maximum time to wait, expressed in milliseconds. Leave empty for infinite wait.
Context : Pattern generator