Origen Export

This page shows how to create static read-only Ruby files from models created by importing 3rd party data (e.g. IP-XACT). The Ruby files can then be used for day-day running of your application and this will significantly improve the boot up speed vs. re-importing the data every time.

The Ruby files can be periodically refreshed as new versions of the master data are released.

The user only need provide the output path where they want the Ruby files to be written.

Implementation

There are two methods for instantiating device models:

  1. As a named Origen TopLevel class with a method #instantiate_sub_blocks to model the device
  2. As a generic SubBlocks module to model the device

Option #1 is the default behavior and is handled in this manner:

$dut.to_origen(path: "#{Origen.root}/output/exported")

Output

At the output path the following files are created:

  • top_level.rb: The top-level object, this is the one that should be instantiated
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only
require_relative 'sub_blocks'
module CrossOrigen
  module Test
    class DUT
      include Origen::Model

      def initialize(options = {})
        sub_block :atx, base_address: 0xDEADBEEF, class_name: 'ATX'
        sub_block # ...
      end
    end
  end
end
  • sub_blocks.rb: include file for the sub_block class files
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only
require_relative 'import/atx.rb'
require_relative # ...
  • import/<sub_block>.rb: models the individual sub_block object
# -*- encoding : utf-8 -*-
# This file is created by Origen, CrossOrigen::OrigenFormat#export, and is read-only.
# If you need to make changes, re-open the class
module CrossOrigen
  module Test
    class DUT
      class ATX # rubocop:disable ClassLength
        include Origen::Model

        def initialize(options = {})
          instantiate_registers(options)
        end

        # rubocop:disable LineLength
        # rubocop:disable StringLiterals
        def instantiate_registers(options = {}) # rubocop:disable MethodLength
          # ** MGATE Clock Divider Register **
          # The MCLKDIV register is used to divide down the frequency of the HBOSCCLK input. If the MCLKDIV
          # register is set to value "N", then the output (beat) frequency of the clock divider is OSCCLK / (N+1). The
          # resulting beats are, in turn, counted by the PTIMER module to control the duration of Flash high-voltage
          # operations.
          reg :mclkdiv, 0x0, size: 16 do |reg|
            # **Oscillator (Hi)** - Firmware FMU clk source selection. (Note that in addition to this firmware-controlled bit, the
            # FMU clock source is also dependent on test and power control discretes).
            # 
            # 0 | FMU clock is the externally supplied bus clock ipg_clk
            # 1 | FMU clock is the internal oscillator from the TFS hardblock
            reg.bit 15, :osch, reset: 0b1, access: :rw
            # ...
          end
          # ...
        end
      end
    end
  end
end

Why option #2? Some Origen applications may serve multiple products and want the ability to swap the current TopLevel model using target instantitation.

origen i -t my_product

Here is a generic example of how an application may use option #2 in combination with the CrossOrigen import feature. By passing the ‘instantiate_level: :sub_block’ to the #to_origen method, the device model is changed to a SubBlocks module implementation. Notice that the #to_origen method is called inside the #on_load_target callback. This is necessary as the #to_origen method accesses Origen.app.output_directory, which is not available until the target is instantiated.

module MyOrigenApp
  class Product
    include Origen::TopLevel
    include CrossOrigen
    
    attr_accessor :curr_prod, :curr_prod_xml, :top_origen_path
        
    def initialize(options = {})
      options = {
        curr_product: nil
      }.update(options)
      @curr_prod = options [:curr_product]
      @curr_prod_xml = Pathname.new("#{Origen.root}/vendor/mycompany/products/#{curr_prod}/product_ipxact.xml")
      @top_origen_path = Pathname.new("#{Origen.root}/vendor/mycompany/products/#{curr_prod}/top_level.rb")
      # Import or instantiate registers
      if @top_origen_path.exist?
        Origen.log.info("Instantiating registers from Origen source for product #{curr_prod}...")
        require @top_origen_path.to_s.chomp(".rb")
        extend SubBlocks
        instantiate_sub_blocks()
      else
        Origen.log.info("Importing IP-XACT registers for #{curr_prod}...")
        cr_import(path: @curr_prod_xml)
      end
    end
    
    def on_load_target
      to_origen(path: @top_origen_path, instantiate_level: :sub_block)
    end
    
  end
end  


Comments