• 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

Documenting Patterns


Origen encourages an agile approach to documentation and pattern generation is no exception. Tools are provided to create test patterns that are self-documenting and by taking a little care you can produce very detailed (and of course 100% accurate) documentation of your test patterns for free.

The pattern generation command has the following switches:

origen g bistcom           # Generate a regular pattern
origen g bistcom --doc     # Output documentation of that pattern to the terminal
origen g bistcom --html    # Generate pre-formatted HTML documentation for inclusion in a web page

The following methods are available to control the documentation output from the pattern generator…

Debug Documentation

Comments that may help with debug of patterns on the tester can be injected into the pattern via the cc method, as with all methods related to pattern documentation this is globally available.

cc "Entering test mode now"
test.mode.write!(RAMBIST_MODE)
reset!

The method argument is a regular string and dynamic segments can be embedded and formatted using any regular Ruby.

delay_cycles = 100
cc "Wait for #{delay_cycles} cycles for the mode to latch"

address = 0x12
cc "Set the target address to: 0x%04X" % address

This will produce pattern output that looks like this:

// Wait for 100 cycles for the mode to latch
// Set the target address to 0x0012

c1 is an alias for cc.

These low level comments will appear in the pattern but they will not be included when a document of the pattern is generated.

A c2 method is available to elevate the importance of a subset of these low level comments such that they will be included in generated documentation.

cc "You won't see me in the docs"
c1 "Or me"
c2 "But you will see me!"

Documenting Major Steps

Major steps in the pattern can be highlighted using the ss method.

ss "Enter RAM BIST mode"

# A block form is also available
ss do
  vdd_core = 1.7
  cc "Enter RAM BIST mode with the following options:"
  cc "  Vdd core - #{vdd_core}v"
end

This will produce the following output in the pattern:

// #######################################################################
// # Enter RAM BIST mode
// #######################################################################

// #######################################################################
// # Enter RAM BIST mode with the following options:
// #   Vdd core - 1.7v
// #######################################################################

Any comments defined in this way are considered more important than the regular cc comments and they will be automatically included in the generated documentation.

Documenting Structure

When presenting documentation it is useful to know something about the structure of the pattern, this allows vectors to be grouped into sections like ‘startup’, ‘shutdown’, etc.

Such structure can be described using the pp method:

pp "Startup" do
  $dut.enter_ram_bist_mode
  $dut.ram.configure_for_test
end

def enter_ram_bist_mode
  pp "Enter RAM BIST mode" do
    # Mode entry code here...
  end
end  

This would produce comments in the pattern that look like this:

// #######################################################################
// # Startup
// #######################################################################

// #######################################################################
// # Enter RAM BIST mode
// #######################################################################

However this difference vs. the ss method is that information about the structure has been provided - it can be determined that the enter RAM bist section is a sub-section of the wider startup sequence.

This comes into play when the pattern documentation is generated as HTML, now we will see something like this (click to expand):

Startup
Enter RAM BIST mode
# Some comments generated by the RAM BIST entry sequence

Adding Annotations

Sometimes it will be helpful to add some annotations to describe what sections of the pattern are doing, this can be done via the annotate method.

Any annotations will not be output in the actual pattern but will be included in generated documentation.

Here is the above example with some annotations added:

pp "Startup" do
  annotate "Perform startup operations that are common to all patterns."
  $dut.enter_ram_bist_mode
  $dut.ram.configure_for_test
end

def enter_ram_bist_mode
  pp "Enter RAM BIST mode" do

    annotate <<-END
      This is an example of a multi-line annotation. Anything you write here
      will be parsed as markdown, so you can do things like:

      * Create bullet
      * Lists

      ~~~ruby
      # Embed some code examples
      $dut.enter_ram_bist_mode
      ~~~

      Or create [links](http://origen.freescale.net)
    END

    # Mode entry code here...
  end
end  

This would produce the following snippet of documentation:

Startup

Perform startup operations that are common to all patterns.

Enter RAM BIST mode

This is an example of a multi-line annotation. Anything you write here will be parsed as markdown, so you can do things like:

  • Create bullet
  • Lists
# Embed some code examples
$dut.enter_ram_bist_mode

Or create links

# Some comments generated by the RAM BIST entry sequence

Summarizing Long Sections

Sometimes it is not necessary to list out every comment or operation when documenting a pattern. For example if the pattern downloads some functional code to be executing on the chip it is not really necessary to include the entire code download in the pattern document.

For these scenarios a snip method is available which will output the given number of documentation lines and then enter a message to indicate that the remainder of the output has been snipped for efficiency.

Here is an example of how to use it, here the comments generated by the contained section will be limited to 10 lines:

  snip 10 do
    # Download some verbose LRE code here
  end

Pattern Headers

When you generate a pattern, you’ll notice the top section contains some useful information, such as the user that generated the pattern, a timestamp, the current environment, version of the application, the gems used, etc. This section is called the pattern header and may look something like this:

// ***************************************************************************
// GENERATED:
//   Time:    24-Jun-2018 10:06AM
//   By:      coreyeng
//   Mode:    debug
//   Command: origen g iterator_postfix_test_x_bx -t debug.rb
// ***************************************************************************
// ENVIRONMENT:
//   Application
//     Source:    git@github.com:Origen-SDK/origen.git
//     Version:   0.33.1
//     Branch:    fixes(c4e8e1d0db0) (+local edits)
//   Origen
//     Source:    https://github.com/Origen-SDK/origen
//     Version:   0.33.1
//   Plugins
//     atp:                      1.1.0
//     origen_core_support:      0.2.3
//     origen_debuggers:         0.6.0
//     origen_doc_helpers:       0.5.2
//     origen_testers:           0.16.1
//     origen_updater:           0.7.0
// ***************************************************************************

The pattern header can also serve as place for the application, current plugin, or other shared plugins, to add specific comments that relate to how that pattern was generated or how it should be used.

Three configuration attributes exist that will inject additional comments into the pattern header: shared_pattern_header, application_pattern_header, and current_plugin_pattern_header.

These configuration attributes should be blocks that accept an options hash and return either a String, Array of Strings, or another block. Strings and Arrays will have the formatting handled for you, but blocks can handle the formatting themselves and can provide custom header comment formatting.

Assume we have two plugins, plugin1 and plugin2 that are each needed to generate a pattern located in the application my_app. With no plugin set and with the configuration attributes set as follows:

# plugin1/config/application.rb

config.shared_pattern_header do
  "Hi from shared #{Origen.app!.name}!"
end

config.current_plugin_pattern_header do
  "Hi from current plugin: #{Origen.app!.name}!"
end

# plugin2/config/application.rb

config.shared_pattern_header do
  "Hi from shared #{Origen.app!.name}!"
end

config.current_plugin_pattern_header do
  "Hi from current plugin: #{Origen.app!.name}!"
end

# my_app/config/application.rb

config.shared_pattern_header do
  "Hi from application #{Origen.app!.name}!"
end

generating a pattern, will yield the following appended to the pattern header:

// ***************************************************************************
// Header Comments From Shared Plugins:
//   Header Comments From Shared Plugin: plugin1:
//     Hi from shared plugin1!
//   Header Comments From Shared Plugin: plugin2:
//     Hi from shared plugin2!
// ***************************************************************************
// Header Comments From Application: my_app:
//   Hi from application my_app!
// ***************************************************************************

You’ll notice here that there’s no current_plugin_pattern_header printed. This will be printed when the current plugin is set to a plugin that has this configuration attribute. Setting the current plugin to plugin1, you’ll now get both shared headers, the current plugin’s header, and the application header:

// ***************************************************************************
// Header Comments From Shared Plugins:
//   Header Comments From Shared Plugin: plugin1:
//     Hi from shared plugin1!
//   Header Comments From Shared Plugin: plugin2:
//     Hi from shared plugin2!
// ***************************************************************************
// Header Comments From The Current Plugin: plugin1:
//   Hi from current plugin plugin1!
// ***************************************************************************
// Header Comments From Application: my_app:
//   Hi from application my_app!
// ***************************************************************************

As previously said, you can provide either a block, proc, or lambda (anything that responds to call will work) and use cc, ss, c2, etc. to handle arbitrary headers or formatting. For example, changing shared_pattern_header in plugin2:

# plugin2/config/application.rb

config.shared_pattern_header do
  proc do 
    c2 "Hi from block in #{Origen.app!.name}"
  end
end

Will show the following in the pattern header:

// ***************************************************************************
// Header Comments From Shared Plugins:
//   Header Comments From Shared Plugin: plugin1:
//     Hi from shared plugin1!
//   Header Comments From Shared Plugin: plugin2:
// Hi from block in plugin2!
// ***************************************************************************
// Header Comments From The Current Plugin: plugin1:
//   Hi from current plugin plugin1!
// ***************************************************************************
// Header Comments From Application: my_app:
//   Hi from application my_app!
// ***************************************************************************
Info: Although the guides here show an option hash, there are currently no options actually being passed in, i.e., its just an empty hash. This is only because this is a new feature, and by using an options hash here, future versions of Origen will be able to add any options that should go to the pattern header without affecting the method prototype.
Deprecated: You may see config.pattern_header in some legacy applications. config.pattern_header is limited to only the current plugin and must handle formatting itself. This is now deprecated but is left in for legacy purposes.

Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license