• 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

Compiler (Views)

Creating Templates


A template is created by taking an existing ASCII file and embedding Ruby snippets to either conditionally include/exclude parts of it or to actually generate content into the output file.

By convention all template files associated with an Origen application live in a sub-directory of the app/templates directory. However it is also possible to compile templates that live outside of the application as long as they are accessible via a path from the Origen application workspace.

Normally templates are identified by appending the extension .erb to the filename. So for example a template for the file dut_regs.h would be called dut_regs.h.erb.

Appending the .erb extension has the following advantages:

  • When Origen is asked to compile a directory only those files ending with the .erb extension will be processed through the compiler. The other files will be copied across to the output directory unmodified. This can be useful if you want to store binaries or some other non-compiler friendly files alongside your template files.
  • If you use an editor like Vim it can be setup to recognize the .erb extension and then syntax highlight the embedded Ruby snippets as Ruby, while highlighting the rest of the template in its native format.

If you would prefer not to have to add the .erb extension add the following to your application configuration, this will cause all files presented to the compiler to be evaluated for embedded Ruby regardless of their name.

# config/application.rb  
config.compile_only_dot_erb_files = false

Template Syntax

The compiler uses a markup language called ERB (embedded Ruby) which ships as part of the Ruby language and has a very minimal and easy to learn syntax. This makes the entire Ruby language available to conditionally include or exclude portions of the file, to expand sections of the file via loops, or to inject dynamic snippets that will be evaluated at runtime. Most importantly of all of course the runtime ERB environment will have full access to the models that have been instantiated by the current target.

Here is an example of a text file to which some ERB has been added:

The ERB syntax is very simple:
% # Lines that start with % (no spaces allowed before it) will be interpreted
% # as Ruby. Since these lines start with a comment character they will simply be
% # deleted by the compilation process - very useful for annotating your source files!

Ruby logic can be used to conditionally include/exclude lines:
% if 1 == 1
  You will see me in the compiled file
% else
  But you won't see me :-(
% end

Loops can be used to expand the content:
% 3.times do
  I must not talk in class
% end

Inject dynamic content like this: 4 + 4 = <%= 4 + 4 %>

Whatever is returned by a Ruby snippet <%= 'like this' %> will be converted to a
string and output to the compiled file.

And not forgetting the best part, you can access any objects that your
target instantiates:

Memory block details:
% $dut.nvm.memories.each_with_index do |mem, i|
  Memory <%= i %>: Version <%= mem.version %>
% end

When this file is processed by the compiler it will look something like this:

The ERB syntax is very simple:

Ruby logic can be used to conditionally include/exclude lines:
  You will see me in the compiled file

Loops can be used to expand the content:
  I must not talk in class
  I must not talk in class
  I must not talk in class

Inject dynamic content like this: 4 + 4 = 8

Whatever is returned by a Ruby snippet like this will be converted to a
string and output to the compiled file.

And not forgetting the best part, you can access any objects that your
target instantiates:

Memory block details:
  Memory 0: Version 12
  Memory 1: Version 12
  Memory 2: Version 12
  Memory 3: Version 12

A Note on State

When compiling multiple templates at once the target will be re-loaded prior to processing each template.

This means that state cannot be carried forward from one template to the next and generally prevents compile order dependent bugs from creeping in due to intentionally or otherwise relying on state that has been setup from a previous template.


Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license