Origen Nexus (0.8.0)

Purpose

This plugin provides an Origen API to use the Nexus protocol.

This plugin supports Read/Write Access of system memory mapped resources, including registers via the conventional Origen Register API.

How To Import

In your Gemfile add:

gem "origen_nexus", ">= 0.8.0"

or if your application is a plugin add this to your .gemspec

spec.add_development_dependency "origen_nexus", ">= 0.8.0"

NOTE: You will also need to require 'origen_nexus' somewhere in your environment. This can be done in config/environment.rb for example.

How To Use

Include the OrigenNexus module to add a Nexus driver to your class and define the required pins, normally the pins would be an alias to existing DUT pins and therefore the driver cannot assume them.

Including the module adds a nexus method which will return an instance of OrigenNexus::Driver.

The driver should be hooked up to the Origen register API by read_register and write_register methods as shown in the example below.

The following attributes can be customized by defining a NEXUS_CONFIG hash:

  • tclk_format - TCLK timing format, Return High (:rh) or Return Low (:rl). Default :rh
  • tclk_multiple - Number of cycles for a single TCLK pulse to cover, to support cases where TCLK needs to be a fraction of another clock period. Assumes 50% duty cycle, specify only even numbers if > 1. Default :r1
  • tdo_strobe - When using multiple cycles for TCK, which state of TCK to strobe for TDO, :tclk_high or :tclk_low or :tclk_all. Default :tclk_high.
  • tdo_store_cycle - When using multiple cycles for TCK, which cycle of TCK to store for TDO if store requested (0 to number of tclk_multiple-1). Default 0
  • once_ocmd_width - Width of OnCE OCMD instruction reg in bits. Default: 10
  • once_nexus_access_instr - Instruction used to access nexus via OnCE. Default: 0x07C
  • once_bypass_instr - Instruction used to bypass OnCE. Default: 0x07F
  • nexus_command_width - Width of Nexus command data regs. Default: 8

Here is an example integration:

class Panther2

  include OrigenNexus

  include Origen::TopLevel

  # TCK covers 4 tester cycles, 2 high then 2 low for each effective TCK pulse
  # Strobe TDO only when TCK high.  Only store TDO on last cycle (3)
  NEXUS_CONFIG = {
    tclk_format:     :rl,
    tclk_multiple:   4,
    tdo_strobe:      :tclk_high,
    tdo_store_cycle: 3
  }

  def initialize
    # Add these required pins (or an alias is fine)
    add_pin :tclk
    add_pin :tdi
    add_pin :tdo
    add_pin :tms

    reg :myreg, 0x007A, size: 32 do |reg|
      reg.bits 31..16, :portb 
      reg.bits 15..8,  :porta 
      reg.bit  0, :enable
    end
  end

  # Hook the Nexus module into the register API, any register read
  # requests will use the Nexus by default
  def read_register(reg, options={})
    nexus.read_register(reg, options)
  end

  # As above for write requests
  def write_register(reg, options={})
    nexus.write_register(reg, options)
  end

  # To write a block of memory
  def write_ram(address, data, options={})
    nexus.block_write_access(address, data, options)
  end

  # To read a block of memory
  def read_ram(address, data, options={})
    nexus.block_read_access(address, data, options)
  end

  # Generate an overlay subroutine for a register
  def overlay_register(reg, options={})
    if tester.respond_to?('start_subroutine')
      tester.start_subroutine(options[:label])
    end

    nexus.write_data_only(reg, options)

    if tester.respond_to?('end_subroutine')
      tester.end_subroutine
    end
  end


end

Panther2.new.myreg.write!(0x55AA55AA)  # => Will perform the write using the Nexus protocol

Panther2.new.myreg.bits(:portA).read!(0xAA)  # => Only the portA bits will be read

Access to the underlying OrigenJTAG hardware driver:

nexus.jtag    # => an instance of OrigenJTAG::Driver

The address can be overridden:

# Transform the default register address
nexus.write_register(reg, address: reg.address << 2)

The driver will also accept flat data values in place of a register.

This can also be used to write to any memory mapped location, even if not a register!

# Write 0x1234 to address 0x12
nexus.write(0x1234, address: 0x12)

# Read and expect 0x1234 from address 0x12
nexus.read(0x1234, address: 0x12)

How To Setup a Development Environment

Clone the repository from Github.

Some patterns can be found in the pattern directory to exercise the protocol.

Follow the instructions here if you want to make a 3rd party app workspace use your development copy of the OrigenNexus plugin: Setting up a Plugin Development Environment

This plugin also contains a test suite, makes sure this passes before committing any changes!

origen test

Comments