• 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

Models

Generic Components


So far we’ve covered SubBlocks, Fuses, Power Domains and other objects. Each of these has its particular use, and its instantiation and customized behavior reflects that, but what about a generic component container?

Origen has one of those too, and it behaves similarly to the aforementioned models. The advantage is that you can get a SubBlock-like or Fuse-like interface without having your generic components registered as a SubBlock or Fuse and without any extra overhead. The disadvantage is that it does nothing else, and functions much like a stripped-down SubBlock object.

However, this allows you to add and use generic components that could be anything. These components don’t require a base address, or any other options (otherwise you’d use a SubBlock) but will still initialize and be kept track for you.

For example, if I have a class: scan_helper, which I’ve implemented as something similar to a SubBlock, but that doesn’t have a base_address, registers, or anything like that, I can instantiate it as a component instead:

component(:scan_helper, class_name: ScanHelper)
#=> ScanHelper instance with name :scan_helper

I can then get this item as I would a sub_block, fuse, etc.:

components[:scan_helper] #=> ScanHelper instance

self.scan_helper #=> ScanHelper instance

Component API

Seems pretty basic, right? Good! That’s what we’re going for! Below is the API that you can do with components.

Adding Components

You can add components in a few different ways:


# Add a component with default class Origen::Component::Default
component(:comp1)

# Add another component. Notice the use component(s).
components(:comp2)

# Add a component of class MyComponent
add_component(:mine, class_name: MyComponent)

# Method add_components also works, as does using a string as the class name
add_components(:also_mine, class_name: 'MyComponent')

# Add a component using block notation
add_components(:block_add) do |comp|
  comp.class_name 'MyComponent'
end

# Add another one using block notation
components(:block_add_2) do |c|
  c.class_name 'MyComponent'
end

Now, if we call just components, we’ll get the resulting Hash storing these. So,


components.keys
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2"]

Notice the switch from :comp1 to "comp1". This is because the underlying Hash is with_indifferent_access.

Therefore, you can get components from the Hash using either a String or a Symbol, but when listing, comparing, etc., the keys will be returned as a String

Adding Multiple Instances

You can add multiple instances at once by passing in the :instances option. This will auto-append an appendix number to each item.

For example:


add_component(:multiple, instances: 4)

components.keys
#=> ["multiple0", "multiple1", "multiple2", "multiple3"]

# In addition, this will make an accessor for each one. So, the following are now defined:

multiple0 #=> :multiple0 Component
multiple1 #=> :multiple1 Component
multiple2 #=> :multiple2 Component
multiple3 #=> :multiple3 Component

You can pass other options in as well. Single options will be applied to all instances. A single option being either not an Array object, or an Array object of size 1.

Options that are Arrays longer than size 1 will be indexed to each instances. For example, if you indicate four instances of a component, Array index 0 will go to instance 0, Array index index 1 to instance 1, and so on. Providing an incompatible Array length will result in an Origen::Componentable::Error.


add_component(:multiple, instances: 4, letter: ['A', 'B', 'C', 'D'], number: 0)

multiple0 #=> :multiple0 Component with parameters: letter: 'A', number: 0
multiple1 #=> :multiple1 Component with parameters: letter: 'B', number: 0
multiple2 #=> :multiple2 Component with parameters: letter: 'C', number: 0
multiple3 #=> :multiple3 Component with parameters: letter: 'D', number: 0

add_component(:more, instances: 3, letter: ['A', 'B', 'C', 'D'], number: 0)
#=> Origen::Componentable::Error

The corner case of wanting a static-sized array given to each instance can be overcome by embedding that Array in another Array of size 1. For example, the options instance: 2, cores: [:cm0, :cm3, :cm4] will result in an Origen::Componentable::Error but, instance: 2, cores: [[:cm0, :cm3, :cm4]] will be fine and results in both instances getting the option cores: [:cm0, :cm3, :cm4].

Copying and Moving Components

You can copy and move components using these methods:


copy_component(:comp1, :comp1_copy)
# Method copy_components is an alias

components.keys
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2", "comp1_copy"]

move_component(:comp1_copy, :comp1_moved)
# Method move_components is an alias

components.keys
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2", "comp1_moved"]

Note that copying components will actually clone the component. So, you get an independent instance of the object that you copied from.

Listing Components

Listing the components will show you just the names. This is the equivalent of using components.keys:


list_components
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2", "comp1_moved"]

You can check if a component has been added using the has_component? method:


has_component?("comp1") #=> true
has_component?(:comp1) #=> true

has_component?("comp_dne") #=> false
has_component?(:comp_dne) #=> false

# component?(name) is an alias method name

Getting Components

You can get components using either the index notation or by utiliting the accessor given during the add process:


components[:comp1] #=> component at name :comp1

comp1 #=> same as calling components[:comp1]

Querying Added Components

There’s a method available that can query the current classes of the added components.


components_of_class(MyComponent)
#=> ["mine", "also_mine", "block_add"]

# components_instances_of and components_of_type are aliases

Enumerating

Component exposes two commonly used enumerable methods: each and select


# All of these call the :each method

components.each do |name, component|
  # do something
end

each_component do |name, component|
  # do something
end

all_components do |name, component|
  # do something
end


select_components do |name, component|
  # do something
end

You can use other enumerable methods provided by the Hash class by using components._enumerable_method_

Deleting Components

You can delete components that you’ve previously added. This will return the deleted item, or raise an exception if the name does not exist.


list_components
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2", "comp1_moved"]

delete_component("comp1_moved")
#=> Component at comp1_moved

list_components
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "block_add_2"]

# Methods delete_components, remove_component, and remove_components, are all aliases

You can also clear the entire component structure and start fresh. Note this this will not return any components.


list_components
#=> ["comp1", "comp2", "mine", "also_mine", "block_add", "comp1_moved"]

delete_all_components

list_components
#=> []

# Methods clear_components and remove_all_components are aliases

Info! Due to the way Component is implemented, it does not an API section. You can see the next topic on Componentable however to extract the component API in YARDOC from its Componentable mixin.

Disabling Accessors

If you add lots of components, or if you add lots of components, subblocks, fuses, etc., it may get messy having each one try to put its own accessor on your model. If you find yourself not wanting components to place accessors on your model, you can define a method :disable_componentable_accessors(klass) and have it return true if klass is of type Origen::Component. In other words:

def disable_componentable_accessors(klass)
  if klass == Origen::Component
    true
  else
    false
  end
end
Warning! Returning a blanket true value will result in all Componentable objects withholding accessors from your model, including components. For more details on this, please see the Componentable Guide.

Componentable

Component is an example of a Origen::Componentable mixin. For information on using this module in your own classes to get a component-like interface, please see the topic here


Comments

Generated with the Origen Semiconductor Developer's Kit

Origen is released under the terms of the MIT license