• 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

Adding Commands


Applications can add their own custom commands to the Origen namespace which makes it very easy to distribute and document custom scripts that support the application environment. Of course like everything else these scripts will have full access to the device models by default.

Commands should be added to the file config/commands.rb in the first instance and as they grow you can extract the larger commands out to their own files.

A skeleton config/commands.rb file should already exist in your application and when an origen command is launched via the command line Origen gives the application command file the first shot at fulfilling it. So in fact it is also possible to override the built-in commands if you ever have a need to do so.

An empty command file has this structure:

aliases ={
}

# The requested command is passed in here as @command, this checks it against
# the above alias table and should not be removed.
@command = aliases[@command] || @command

# Now branch to the specific task code
case @command

else
  @application_commands = <<-END
  END

end 

When the command is launched the first argument, the command name, will be available in the instance variable @command. Your code should interrogate this variable to decide whether the command request is one that should be handled by your application, or else left for Origen to dispatch (in the skeleton commands file all requests are simply passed through to Origen by default).

Let’s say for example that we want to implement a command that will print the current time, we could accomplish this like so:

aliases ={
  "time" => "current_time"
}

# The requested command is passed in here as @command, this checks it against
# the above alias table and should not be removed.
@command = aliases[@command] || @command

# Now branch to the specific task code
case @command

when "current_time"
  puts Time.now
  exit 0

else
  @application_commands = <<-END
 current_time      Print the current time (aliased as "time") 
  END

end 

The following points are worth noting from this example:

  • We implemented an alias of “time” for the “current_time” command. This means that it can be launched either via origen current_time or the more succinct origen time. The use of aliases is completely at your discretion and they are not required.
  • The command code should always complete with exit 0. This is to end the current command request since otherwise the request will then fall through to Origen which will attempt to process it.
  • You can document your commands via the @application_commands variable, this should be a simple one liner that describes what your command does. This information will be available to the user when they run origen -h. More detailed documentation for your command can be added by adding support for command options (see below).

Loading the Application

Such commands will execute very quickly since they don’t bother to load any of your application environment, but what if you need to access your models?

The application will load automatically anytime you reference Origen.app, this will load your config/boot.rb file and all of your models and other logic will then become available. One other useful side effect of this for scripting purposes is that it will make the root directory of your application available via Origen.root.

For example:

MyClass.do_something    # => I want to access my code here but this is giving an error

Origen.app   # Make a reference to the application, this will load it if is not already loaded

MyClass.do_something    # => Now it works

Loading the Target

See the dedicated section on Programming the Runtime Environment.

Handling Command Options

Most scripts will benefit from giving the user some options to configure the behavior and this is easy to add. Any command arguments or options passed in by the user will be available via the ARGV array.

Note!

-d is a reserved option which you cannot use, Origen uses this to enable the debugger and will strip it out of ARGV before handing it over to your command code.

You can actually query this variable manually to decide what to do, but it is recommended that you use the Ruby OptionParser library which makes it very easy to both parse user options and to document them.

Let’s say that we wanted to give the user the ability to specify what format the time should be presented in by using the strftime method. This could be accomplished like this:

aliases ={
  "time" => "current_time"
}

# The requested command is passed in here as @command, this checks it against
# the above alias table and should not be removed.
@command = aliases[@command] || @command

# Now branch to the specific task code
case @command

when "current_time"
  options = {}
  opt_parser = OptionParser.new do |opts|
    opts.banner = <<-END_DESC
 origen time - This command will print the current time using the default Time
               format, alternatively specify your own format via the -f option.
    END_DESC
    opts.on("-f", "--format FORMAT", String, "FORMAT should use strftime notation") { |t| options[:format] = t }
    opts.separator ""
    opts.on("-h", "--help", "Show this message") { puts opts; exit }
  end
  opt_parser.parse! ARGV

  if options[:format]
    puts Time.now.strftime(options[:format])
  else
    puts Time.now
  end
  exit 0

else
  @application_commands = <<-END
 current_time      Print the current time (aliased as "time") 
  END

end 

Note the following in the above example:

  • We initially declare an empty hash called options which we will then populate based on the user input.
  • opts.banner can be used to specify a detailed description of how the command works. This is used in conjunction with the -h option which we have handled at the bottom. This should be included in all of your commands to provided a consistent user interface, the user can now run origen time -h to display the command description and a summary of all available options. The -h implementation is an example of how to handle Boolean options.
  • The -f option itself is implemented as an option that accepts a String parameter, which we collect and place in the options hash to make it easily available to downstream code. This allows the user to run origen time -f "%Y" for example which will display the current year only.

Moving To a New File

As your application becomes more complex you will find that you want to organize your commands better instead of having them all dumped into a single file.

In this case we could extract the command code above into the application library, lib/commands/current_time.rb, for example, and then include it like this:

aliases ={
  "time" => "current_time"
}

# The requested command is passed in here as @command, this checks it against
# the above alias table and should not be removed.
@command = aliases[@command] || @command

# Now branch to the specific task code
case @command

when "current_time"
  require "commands/current_time"
  exit 0

else
  @application_commands = <<-END
 current_time      Print the current time (aliased as "time") 
  END

end 

More Examples

This is obviously a very trivial example and real commands can grow to be infinitely complex. For some real world examples you can look at the implementation of the built in Origen commands which have been implemented using the same techniques described above.

Also be sure to check out the OptionParser documentation which contains further examples and documentation on option parsing.


Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license