• 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

Creating Patterns


Patterns are generated by regular Ruby files that should live within the pattern directory - a sub-directory within there is fine and is in fact encouraged to help keep things organized as the number of patterns increases. However keep in mind that each pattern should be uniquely named - i.e. no other files of the same name should live in any of the sub-directories of pattern.

Each pattern file should have the following structure:

Pattern.create do
  # Pattern specific content goes here
end

Startup and Shutdown Sequences

Startup and shutdown sequences will generally be the same for all patterns and these should be implemented by using the callbacks that support pattern generation.

Any options supplied to Pattern.create will be passed into the startup and shutdown methods when they are called, thereby providing a mechanism for per-pattern customization of the startup/shutdown sequences.

Here is an example of an SoC controller with some startup and shutdown callbacks implemented:

class MyDeviceController
  include Origen::Controller

  def startup(options)
    options = {
      mode: :functional_test,
    }.merge(options)
    if options[:mode] == :functional_test
      enter_functional_test_mode
    elsif options[:mode] == :bist
      enter_bist_test_mode
    else
      raise "Unknown mode requested - #{options[:mode]}"
    end
  end

  def shutdown(options)
    options = {
      reset: true,
    }.merge(options)
    reset_device if options[:reset]
  end
end

So by default this pattern will enter functional test mode at the start and reset the device at the end:

Pattern.create do
  # Pattern specific content goes here
end

This one will enter BIST mode instead at the start:

Pattern.create(mode: :bist) do
  # Pattern specific content goes here
end

and this one would exit without resetting the device:

Pattern.create(mode: :bist, reset: false) do
  # Pattern specific content goes here
end
Note - The top-level is guaranteed to be called first and last for the startup and shutdown callbacks respectively. However the calling order of lower level startup/shutdown listeners is undefined, if you have multiple and care about the order you should designate one as the master which will be called by Origen, it should then co-ordinate calling any additional startup/shutdown methods as required.

The Golden Rules for Building Maintainable Patterns

Origen provides a framework in which you can build very complex patterns that remain easy to maintain, but as with any tool it is also possible to use it to create something with which to hang yourself!

In order to avoid going down a path that will lead to an unmaintainable mess, it is strongly recommended that the following rules are observed:

  • Patterns should not talk to the current tester object directly
  • Patterns should not attempt to control pin states
  • Patterns should not attempt to access registers directly

Probably the most tempting one to break is the last one, however generally manipulating register states outside of the owning model is a sign of poor application design and breaking the encapsulation that should be provided by a model representing a silicon module. Instead the model’s controller should provide an external interface which would remain constant even if the internal operation of a given operation changes significantly from one silicon revision to the next. See the Controller guides for more.

If the above rules are followed pattern source files should typically be very small and should generally only call a handful of methods on the target object(s), here are a few examples:

# Pattern to measure the output of the Vreg module
Pattern.create do
  $dut.vreg.measure
end
# Pattern to measure the output of the Vreg module for a specific setting
Pattern.create do
  $dut.vreg.measure(setting: 12)
end
# Pattern to program a checkerboard and then read it
Pattern.create do
  $dut.nvm.program(pattern: :ckbd)
  $dut.nvm.read(pattern: :ckbd)
end

Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license