• 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

Miscellaneous

Utilities & Helpers


Origen provides some general-purpose utlity classes and modules that can help you to better develop your applications, plugins, and other features. The following is a list of the utilities currently implemented by Origen:

  • Block Args
  • Collector
  • CSV Data
  • Diff
  • File Diff
  • Input Capture
  • Mailer
  • Time And Date
  • Block Args

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.

    Collector

    You may notice some features within Origen, such as registers, bits, or anything that uses componentable to instantiate, are able to take either an options hash or an options block and merge the two, allowing users to work with whichever is preferred. Under the hood of these features, is the Collector, which allows for a block to be transformed into a hash and can then be used as options for the given feature.

    The collector is available at Origen::Utility::Collector, but a shortcut method to create a new instance is available as Origen::Utility.collector. The collector isn’t really meant to be used throughout, rather it is an intermediary step to join hashes and blocks. An example of using the collector is:

    block = Proc.new do |collector|
      collector.arg1 'argument 1'
      collector.arg2 'argument 2'
    end
    
    collector = Origen::Utility.collector
    block.call(collector)
    
    collector.to_h
    #=> {arg1: 'argument 1', arg2: 'argument 2'}
    

    The result of using the collector is that each argument given as a method is transformed into a hash key/value pair.

    No Value Given

    If a method is given without a value, it will be defined and set to nil, as shown below:

    block = Proc.new do |collector|
      collector.arg1
    end
    
    collector = Origen::Utility.collector
    block.call(collector)
    
    collector.to_h
    #=> {arg1: nil}
    

    Using An Anonymous Collector

    As previously stated, one use of the collector is to transform an option block into an option hash and/or merge an existingoption hash and the resulting option hash. This allows for options to be given either as a hash or as a block or both, depending on the nature of the options and the preference of the user. In these cases, it is common to just instantiate the collector, convert it to a hash, then throw it away. This can be done in a single line as:

    collector = Origen::Utility.collector(&block).to_h
    
    Danger! This syntax will always work, but other syntaxes have some hidden dangers. See later in this page for details

    Merging Options

    The collector allows for automatic hash merging. The intent is to easily allow for an options hash and an options block to merge into a single combined hash. This can be achieved by passing in two options during collector initialization: hash and merge_method.

    # Combining a hash and block with no clashes
    options = {argA: 'arg A', argB: 'arg B'}
    block = Proc.new do |collector|
      collector.arg1 'arg 1'
      collector.arg2 'arg 2'
    end
    Origen::Utility.collector(hash: options, &block).to_h
      #=> {argA: 'arg A', argB: 'arg B', arg1: 'arg 1', arg2: 'arg 2'}
    
    # Combining a hash and block with some keys clashing (default merging)
    options = {arg1: 'has arg 1', arg2: 'hash arg 2'}
    block = Proc.new do |collector|
      collector.arg2 'block arg 2'
      collector.arg3 'block arg 3'
    end
    Origen::Utility.collector(hash: options, &block).to_h
      #=> {arg1: 'has arg 1', arg2: 'hash arg 2', arg3: 'block arg 3'}
    
    # Combining a hash and block with explicit merge method :keep_hash (default)
    options = {arg1: 'has arg 1', arg2: 'hash arg 2'}
    block = Proc.new do |collector|
      collector.arg2 'block arg 2'
      collector.arg3 'block arg 3'
    end
    Origen::Utility.collector(hash: options, merge_method: :keep_hash, &block).to_h
      #=> {arg1: 'has arg 1', arg2: 'hash arg 2', arg3: 'block arg 3'}
    

    As shown, of the options that were given to both the hash and the block, the options in the hash were kept. This is the default behavior, or can be explicitly defined by providing merge_method: :keep_hash to avoid confusion.

    Info! Running the collector without a block will always be just the input hash.

    Two other merge method exists: :keep_block and :fail. :keep_block is just the opposite of :keep_hash and :fail will raise an error if the same option is provided by both the hash and the block. Trying to set the merge_method to anything else will raise an error.

    options = {arg1: 'has arg 1', arg2: 'hash arg 2'}
    block = Proc.new do |collector|
      collector.arg2 'block arg 2'
      collector.arg3 'block arg 3'
    end
    Origen::Utility.collector(hash: options, merge_method: :keep_block, &block).to_h
      #=> {arg1: 'has arg 1', arg2: 'block arg 2', arg3: 'block arg 3'}
    
    options = {arg1: 'has arg 1', arg2: 'hash arg 2'}
    block = Proc.new do |collector|
      collector.arg3 'block arg 3'
    end
    Origen::Utility.collector(hash: options, merge_method: :fail, &block).to_h
      #=> {arg1: 'has arg 1', arg2: 'hash arg 2', arg3: 'block arg 3'}
    
    options = {arg1: 'has arg 1', arg2: 'hash arg 2'}
    block = Proc.new do |collector|
      collector.arg2 'block arg 2'
      collector.arg3 'block arg 3'
    end
    Origen::Utility.collector(hash: options, merge_method: :fail, &block).to_h
      #=> Origen::OrigenError
      #=> 'Origen::Utility::Collector detected both the hash and block attempting to set :arg2 (merge_method set to :fail)'
    

    Failure Conditions

    As shown above, trying to merge the same key in the hash and block when merge_method: :fail will cause an exception. There are a few other conditions that will cause the collector to fail.

    Since the collector tries to transform an options block into a hash, some of the syntactic rules of hashes are enforced on blocks.

    Multiple Sets

    The collector will fail if the same method is set after multiple times. For example:

    block = Proc.new do |collector|
      collector.arg1 'hi'
      collector.arg1 = 'hello'
    end
    Origen::Utility.collector(&block)
      #=> ArgumentError
    

    Even though this is technically allowed in Ruby, its the equalivent of a hash formatted {arg1: 1, arg1: 2}, which just overwrites values. There is no reason for this usage and it just causes confusion (especially in large hashes or blocks), so the collector disallows this.

    Multiple Values In A Single Set

    Each method can only set one value. As such, providing any number of arguments greater than one will fail, as will attempting to use both an argument and a block.

    For example:

    block = Proc.new do |collector|
      collector.arg1 'arg1', 'arg2', 'arg3'
    end
    Origen::Utility.collector(&block)
      #=> ArgumentError
    
    block = Proc.new do |collector|
      collector.arg1('arg1') do
        'nothing'
      end
    end
    Origen::Utility.collector(&block)
      #=> ArgumentError
    

    This would be the hash equalivent of {arg1: 'arg1', 'arg2', 'arg3'} which is a syntax error. Also, setting a value to just a block is accepted, just not a block and another value simultaneously.

    Caveats of Anonymous Collectors

    For the collector, method_missing actually returns self, instead of the value set. This means that blocks that only use the collector.arg value notation will always return the collector. The advertised means of using an anonymous collector is:

    Origen::Utility.collector(options, &block)
    

    However, the following may work, depending on the block:

    block.call(Origen::Utility.collector)
    

    For the above case, in order to get a collector instance, the block must return the collector. If just using collector.arg val syntax, this will work, but collector.arg = val syntax will not. This is due to Ruby’s rules that collector.arg = val will return val. Likewise, adding other stuff at the end of the block will also change its return value:

    block = Proc.new do |collector|
      collector.arg1 'arg1'
    end
    block.call(Origen::utility.collector)
      #=> Collector Instance
    
    block = Proc.new do |collector|
      collector.arg1 = 'arg1'
    end
    block.call(Origen::utility.collector)
      #=> 'arg1'
    
    block = Proc.new do |collector|
      collector.arg1 'arg1'
      'random stuff'
    end
    block.call(Origen::utility.collector)
      #=> 'random stuff'
    

    However, if the block returns the collector itself, as below:

    block = Proc.new do |collector|
      collector.arg1 'arg1'
      'random stuff'
      collector
    end
    block.call(Origen::utility.collector)
      #=> Collector Instance
    

    then this will work as expected. But, this relies on the block being written in a way that is impossible to detect from the collector itself.

    The correct way to work around this is to use the advertised means of initializing an anonymous collector. This will give you the desired result regardless of the block’s return value.

    block = Proc.new do |collector|
      collector.arg1 'arg1'
    end
    Origen::utility.collector(&block)
      #=> Collector Instance
    
    block = Proc.new do |collector|
      collector.arg1 = 'arg1'
    end
    Origen::utility.collector(&block)
      #=> Collector Instance
    
    block = Proc.new do |collector|
      collector.arg1 'arg1'
      'random stuff'
    end
    Origen::utility.collector(&block)
      #=> Collector Instance
    

    CSV Data

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.

    Diff

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.

    File Diff

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.

    Input Capture

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.

    Mailer

    Usage of the mailer in applications or plugins is described at sending emails and maillists.

    As a quick recap of the above, you can send an email using Origen’s mailer:

    Origen.mailer.send_email(subject: "Hello", to: ['user@domain.com', 'other_user@domain.com'], body: message)
    

    The subject, to, and from options are the most used but you can get a test email sent to the current user (yourself) by omitting all the options:

    Origen.mailer.send_email
      #=> to: current user's email
      #=> from: current user's email
      #=> subject: 'Hello'
      #=> body: 'Hello from Origen!'
    

    However, that assumes a working mailer setup. In order to use the mailer, either the user, in the options, or the site administator will need to setup the mailer correctly. It is recommended that the mailer be setup in the Site Config, allowing all users to use the same configuration. However, each option can be overridden when using the mailer directly.

    For the mailer’s options in the site config, please see the default site config.

    Origen’s mailer is just a wrapper around Ruby’s net/smtp library. When using a SMTP server, you’ll need to supply the server, port, and domain values. These can come from the site config as keys:

    email_domain: company.com
    email_server: smtp.company.net
    email_port: 25
    

    Or can be passed in as options:

    Origen.mailer.send_email(
      domain: 'company.com',
      server: 'smtp.company.net',
      port: 25,
    )
    

    For non-authenticating SMTP servers, that is usually sufficient. For servers which require that the requester supply some credentials, you can also supply an authentication customization either in the site config:

    email_authentication: login
    

    Or as an option:

    Origen.mailer.send_email(authentication: :login)
    

    The username and password will default to the current user’s credentials, Origen.current_user.email and Origen.current_user.password respectively, and, in general, this should be adequate. However, these can be overwritten if, for example, a service account is used instead of the active user’s account:

    email_auth_user: service_user_email
    email_auth_password: service_user_password
    
    Origen.mailer.send_email(
      authentication: :login,
      auth_user: 'service_user_email',
      auth_password: 'service_user_password',
    )
    

    You can reference Origen’s wrapper around SMTP on Github.

    Time And Date

    Sorry, Documentation Fail

    Unfortunately this guide has not been written yet, but it is an area that is on our road map.

    Please comment below to let us know that you were looking for it, this will help us to prioritize which sections to write next.

    If you need help on this item in the meantime, please ask a question in the Origen forum.


    Comments

    Generated with the Origen Semiconductor Developer's Kit

    Origen is released under the terms of the MIT license