• Guides
  • Videos
  • Publications
  • API
  • Github
  • Community
  • Release Notes
  • Plugins
Installing Origen
  • Introduction
  • How to Install
  • How to Install (Windows)
  • Company Customization
  • Understanding Gems
  • Invoking Considerations
  • Workspace Management
Getting Started with Origen
  • Core concepts
  • Creating a New App
  • Directory Structure
  • The Initial Commit
  • Creating New Files
  • Understanding Blocks
  • Application Architecture
Runtime Environment
  • Introduction
  • Mode
  • Environment
  • Target
  • Production Targets
  • Global Setup
  • Load Order
  • Programming
Models
  • Introduction
  • Naming
  • Definition & Hierarchy
  • Adding Attributes
  • Versioning
  • Bugs & Features
  • Package, Mode & Configuration
  • Registers
  • Pins
  • Power Domains
  • Hardware Attributes
  • Parameters
  • Specifications
  • Fuses
  • Generic Components
  • Creating Your Own Components
Compiler (Views)
  • Introduction
  • Creating Templates
  • Using Sub-Templates
  • Helpers
  • Running The Compiler
  • Inline Compiler
Controllers
  • Introduction
  • Shadow Controllers
  • Direct Controllers
Pattern Generator
  • Introduction
  • Creating Patterns
  • Pins
  • Timing and Waiting
  • Registers
  • Documenting Patterns
  • Generating by Name
  • Common API
  • J750 API
  • V93K API
  • UltraFlex API
  • STIL & Other Formats
  • Custom Testers
  • Running The PatGen
  • Concurrent Patterns
Test Program Generator
  • Introduction
  • Philosophy
  • Creating Flows
  • Managing Flow Control
  • Creating an Interface
  • Additional Resources
  • Dynamic Custom Code
  • Characterization API
  • J750 API
  • V93K Common API
  • V93K SMT7 API
  • V93K SMT8 API
  • UltraFLEX API
  • Documenting the Program
  • Creating Custom Testers
  • Running the ProgGen
Decompilation
  • Overview & Example
  • Decompiling, Adding Pins, & Executing
  • Working with Decompiled Patterns
  • Platform Specifics
Simulation
  • Introduction
  • How It Works
  • Compiling the DUT
  • AMS Support
  • Environment Setup
  • Application Setup
  • Simulating Patterns
  • Simulating Flows
  • Direct DUT Manipulation
  • Simulator Log Output
  • Artifacts
  • Debugging
Documentation Generator
  • Introduction
  • Markdown
  • Linking
  • Styling
  • Testing
  • API Generation
  • Deploying
Plugins
  • Introduction
  • Using a Plugin
  • Creating a Plugin
  • Current & Default Plugins
  • Dev Environment
  • Dev Considerations
  • Paths & Origen.root
  • Config & Origen.app
Miscellaneous
  • Revision Control
  • Origen Remotes
  • Lint Testing
  • Session Store
  • LSF API
  • Users, Emails & Maillists
  • Utilities & Helpers
  • Ruby Extensions
  • Logger
  • Adding Commands
  • Overriding Commands
  • Callbacks
  • Application Callbacks
  • Miscellaneous Topics
Advanced Topics
  • Introduction
  • Invocation Customization
  • Custom App Generators

Pattern Generator

Common API


All tester drivers support the common API described in this guide. By building your patterns using this API your will be able to generate them for any ATE that is supported by Origen.

Some tester drivers may expose additional methods to leverage some key features of the given ATE which do not have direct equivalents on other systems. You may or may not choose to use these in your application. If you do, then be aware that you are introducing some logic which cannot be automatically translated to other ATEs. In that case you will have to implement the alternative implementation for other platforms on the application side, something like this:

if $tester.uflex?
  # An implementation that uses a method that only exists on the UltraFLEX driver,
  # this will make the test run more efficiently on that platform
else
  # Conventional implementation using the common API for all other platforms
end

Of course some applications may only ever wish to target a specific ATE, in that case you can freely pick from the common and ATE-specific APIs.

This API is currently provided by the Origen Testers plugin. In addition to the primary methods discussed below, all tester drivers support the methods described in the following API docs:

  • OrigenTesters::VectorGenerator
  • OrigenTesters::Timing
  • OrigenTesters::API

API Methods

Here are each of the main methods supported by the common API.

Generating Cycles

These are the basic methods for generating vectors.

cycle(options = {})

Generate a tester cycle or cycles:

$tester.cycle
$tester.cycle repeat: 1000

As this is such a commonly used method, there are some convenience methods available, this is equivalent to the above example:

1.cycle
1000.cycles

A very common pattern when working at this level is to setup some pin states and then trigger a cycle:

pin(:tdi).drive(1)
$tester.cycle
pin(:tdi).drive(0)
$tester.cycle

All of the pin state methods support a bang (!) variant which will automatically call a single cycle after setting the pin state, this is equivalent to the above:

pin(:tdi).drive!(1)
pin(:tdi).drive!(0)
wait(options = {})

Repeats the last vector for the specified about of time. The time can be specified in cycles or a time, multiple arguments will be added together:

$tester.wait cycles: 1000         # Equivalent to $tester.cycle(repeat: 1000)
$tester.wait time_in_us: 1000     # Wait for 1000us
$tester.wait time_in_ms: 1        # Wait for 1ms

$tester.wait time_in_ms: 1, time_in_us: 1000, cycles: 100     # Wait for 2ms + 100 cycles

The wait method can also be called with additional arguments to generate a dynamic wait, i.e. a match loop. Here for example to wait for up to 2 seconds for the done pin to go high:

$tester.wait match: true, time_in_s: 2, pin: pin(:done), state: :high

The above API is somewhat verbose, a cleaner one is available by supplying a block to generate the vectors which much pass for the match to resolve. This is equivalent to the previous example:

$tester.wait match: true, time_in_s: 2 do
  pin(:done).assert!(1)
end

This block form also allows much more complex match conditions to be described, here to wait for either the fail pin to go high, OR the done pin to go high:

$tester.wait match: true, time_in_s: 2 do |conditions, fail|
  conditions.add do
    pin(:done).assert!(1)
  end
  conditions.add do
    pin(:fail).assert!(1)
  end
end

To AND these conditions would simply be:

$tester.wait match: true, time_in_s: 2 do
  pin(:done).assert(1)
  pin(:fail).assert(1)
  1.cycle
end
ignore_fails(*pins)

Ignore fails on the given pins for the duration of the given block, this has the effect of temporarily setting the states of the given pins to don’t care.

# Temporarily ignore mis-compares on the fail and data pins
$tester.ignore_fails(pin(:fail), pins(:data)) do
  # Any vectors generated in here will force the state of the given pins to X
end

Data Capture

store(*pins)

Instruct the tester to capture the data on the given pins from the vector that was generated last, note that it does not actually generate a new vector.

Sometimes when generating vectors within a loop you may want to retrospectively capture a previous vector, passing in an offset option will allow you to do this.

Here are some examples:

$tester.cycle                        # This is the vector that we want to capture
$tester.store pin(:d0), pin(:d1)     # Capture the data on the d0 and d1 pins

$tester.cycle                        # This one gets stored
$tester.cycle
$tester.cycle
$tester.store pin(:d0), pin(:d1), offset: -2  # Just realized I need to capture that earlier vector

Note that this API is for engineers who are writing protocol drivers, most test IP would be written at a higher level, e.g.

atd_result.data.store!   # Capture the value of the ATD result bits to the tester
store_next_cycle(*pins)

Similar to the above, this API allows driver creators to indicate that the next vector, wherever that may be generated, should be captured:

$tester.store_next_cycle pin(:d0), pin(:d1)

# This is the vector that will be captured, in real life this could be done after returning
# to a caller
$tester.cycle  
capture_style

Testers support different ways of capturing vector data. For all tester types the default capture style is hram (history ram). For UltraFlex digcap is additionally supported. Change from the default like this:

# change capture style
# if the digcap isn't support for the current tester, default behavior (hram) is used
tester.capture_style = :digcap

# change back to hram capture style
tester.capture_style = :hram

# temporarily change the capture style for this cycle
tester.store_next_cycle pin(:d0), capture_style: :digcap
configure capture memory

Origen will create any instrument definitions required when capture memory is used. However, it may be desirable to alter the configuration settings. Here is an example of how to do this:

# configure TDO as a 16-bit instrument (default size is the number of pins - 1 in this case)
tester.capture_memory :digcap do |mem|
  mem.pin :tdo, size: 16
end

Data Source

overlay

Testers support different ways of modifying vector data during run time. This practice is referred to here as “overlay”. Overlay is requested through an optional argument to cycle:

# setup overlay parameters
overlay_options = {}
# Required - what pin(s) are being overlayed?
overlay_options[:pins] = dut.pin(:tdi)
# Required - what is the overlay string? This will become a label or subroutine name
overlay_options[:overlay_str] = ovl_reg[i].overlay_str

tester.cycle overlay: overlay_options

# Generate another overlay cycle, holding the same data as the previous cycle
overlay_options[:change_data] = false
tester.cycle overlay: overlay_options

# Now a new piece of data needs to be sent
overlay_options[:change_data] = true
tester.cycle overlay: overlay_options
overlay_style

The default overlay style is subroutine (vectors that will be modified are replaced by a call to a subroutine). Change from the default like this:

# if requested sytle is not available for the current tester it will default to :subroutine
tester.overlay_style = :digsrc
tester.overlay_style = :subroutine
tester.overlay_style = :label
tester.overlay_style = :handshake

# change the overlay style for this cycle only by adding :overlay_style to the overlay_options
overlay_options[:overlay_style] = :label
tester.cycle overlay: overlay_options

Not all overlay styles are supported on all testers and if the requested style is not supported a warning will be logged and it will fall back to the default style (:subroutine).

Here is a brief summary of what each type does:

digsrc
The vectors to be modified are updated with the data value held in a tester memory.
subroutine
The vectors to be modified are removed from the pattern and replaced by a call to a another (subroutine) pattern.
label
A label is inserted into the pattern immediately before the vectors to be modified.
handshake
The vectors to be modified are removed from the pattern and replaced by a handshake with the tester.
configure source memory

Origen will create any necessary instruments statements. Add configuration information to source memory like this:

tester.source_memory do |mem|
  mem.pin :tdi, size: 32, format: :binary, data_type: :long
end

Subroutines

start_subroutine(name), end_subroutine

Use these methods to write a pattern subroutine:

$tester.start_subroutine "wait_for_done"
$tester.wait match: true, time_in_s: 2 do
  pin(:done).assert!(1)
end
$tester.end_subroutine
call_subroutine(name, options = {})

Call a pattern subroutine, an offset can be given to retrospectively jump to a subroutine from a previous vector:

$tester.call_subroutine "wait_for_done"
1.cycle
1.cycle    #  A branch will also be made after completing this vector
1.cycle
1.cycle
$tester.call_subroutine "wait_for_done", offset: -2

Loops and Branching

label(name)

Inject an arbitrary label into the pattern:

$tester.label "on_failed"
branch_to(label)

Branch to a label:

$tester.branch_to "on_failed"
loop_vectors(name, number_of_loops)

Execute the vectors generated within the given block n times:

$tester.loop_vectors("my_loop", 3) do   # Do this 3 times...
  $tester.cycle
end

Miscellaneous

freq_count(pin)

Setup to measure the frequency on the given pin:

$tester.freq_count pin(:clk_out)
microcode(code, options = {})

This can be used to inject arbitrary microcode into the pattern, which of course is inherently coupling your logic to a specific test platform - so use sparingly!

An offset can be given to apply the microcode to previously generated vectors.

$tester.microcode 'set_cpu (cpuC)'
1.cycle
1.cycle    # cpuB will be set here 
1.cycle
1.cycle
$tester.microcode 'set_cpu (cpuB)', offset: -2
Free-Running Clock on Existing Pin

Set up a pin to be a free-running clock with the vector generation (with respect to toggling the pin at the appropriate intervals) automatically taken care of.

See Pin Clock Functionality for details on the API.


Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license