class Origen::Registers::BitCollection

This is a regular Ruby array that is used to store collections of Bit objects, it has additional methods added to allow interaction with the contained bits. All Ruby array methods are also available - www.ruby-doc.org/core/classes/Array.html

A BitCollection is returned whenever a subset of bits is requested from a register. Also whenever any of these methods are called on a register object a BitCollection is created on the fly that contains all bits in the register. This means that when interacting with a Register, a single Bit, or a group of Bit objects, the same API can be used as described below.

Constants

DONT_CARE_CHAR
OVERLAY_CHAR
STORE_CHAR
UNKNOWN_CHAR

Attributes

id[RW]
name[RW]

Public Class Methods

dummy(reg, name = nil, options = {}) click to toggle source

Returns a dummy bit collection that is populated with un-writable bits that will read back as 0. This can be useful for padding out spaces in registers with something that responds like conventional bits.

# File lib/origen/registers/bit_collection.rb, line 302
def self.dummy(reg, name = nil, options = {})
  name, options = nil, name if name.is_a?(Hash)
  options = {
    size: 8,
    pos:  0
  }.merge(options)
  collection = new(reg, name)
  pos = options[:pos]
  options[:size].times do
    bit = Bit.new(reg, pos, writable: false, feature: :dummy_feature)
    collection << bit
    pos += 1
  end
  collection
end

Public Instance Methods

[](*indexes) click to toggle source

Access bits by index

Note This method behaves differently depending on the setting of @with_bit_order

If @with_bit_order == :lsb0 (default) index 0 refers to the lsb of the bit collection If @with_bit_order == :msb0 index 0 refers to the msb of the bit collection

Example

dut.reg(:some_reg).bits(:some_field).with_msb0[0..1] # returns 2 most significant bits
dut.reg(:some_reg).bits(:some_field)[0..1]           # returns 2 least significant bits

Note Internal methods should call this method using a with_lsb0 block around the code or alternatively use the shift_out methods

Example

with_lsb0 do
  saved_bit = [index]
  [index] = some_new_bit_or_operation
end
# File lib/origen/registers/bit_collection.rb, line 89
def [](*indexes)
  return self if indexes.empty?

  b = BitCollection.new(parent, name)
  expand_and_order(*indexes).each do |i|
    b << fetch(i)
  end
  # When 1 bit requested just return that bit, this is consistent with the original
  # behaviour before sub collections were added
  if b.size == 1
    b.first
  else
    # maintain downstream bit numbering setting
    @with_bit_order == :msb0 ? b.with_msb0 : b
  end
end
Also aliased as: bits, bit
abs_path() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 130
def abs_path
  first.abs_path
end
access(value = nil) click to toggle source

Returns the access attribute of the first contained bit, in most normal use cases the application will naturally guarantee that when this is called all of the bits in the collection have the same access value.

If you are worried about hitting the case where some bits have different values then use access!, but this will be a bit less efficient

# File lib/origen/registers/bit_collection.rb, line 249
def access(value = nil)
  if value.nil?
    first.access
  else # set access
    each { |b| b.set_access(value) }
    self
  end
end
access!() click to toggle source

Like access but will raise an error if not all bits in the collection have the same access value

# File lib/origen/registers/bit_collection.rb, line 260
def access!
  val = access
  if any? { |b| b.access != val }
    fail 'Not all bits the collection have the same access value!'
  end

  val
end
append_overlays(value) click to toggle source

Append a value, for example a block identifier, to all overlays

Example

reg(:data).overlay("data_val")
reg(:data).append_overlays("_0")
reg(:data).overlay_str           # => "data_val_0"
# File lib/origen/registers/bit_collection.rb, line 704
def append_overlays(value)
  each do |bit|
    bit.overlay(bit.overlay_str + value) if bit.has_overlay?
  end
  self
end
assert!(value = nil, options = {})
Alias for: read!
bind(live_parameter) click to toggle source
# File lib/origen/registers/bit_collection.rb, line 67
def bind(live_parameter)
  parent.bind(name, live_parameter)
end
bit(*indexes)
Alias for: []
bit_order() click to toggle source

Returns the bit order of the parent register

# File lib/origen/registers/bit_collection.rb, line 34
def bit_order
  parent.bit_order
end
bit_value_descriptions(_bitname = nil) click to toggle source
# File lib/origen/registers/bit_collection.rb, line 290
def bit_value_descriptions(_bitname = nil)
  options = _bitname.is_a?(Hash) ? _bitname : {}
  if name == :unknown
    []
  else
    @reg.bit_value_descriptions(name, options)
  end
end
bits(*indexes)
Alias for: []
clear_flags() click to toggle source

Calls the clear_flags method on all bits, see Bit#clear_flags for more details

# File lib/origen/registers/bit_collection.rb, line 528
def clear_flags
  each(&:clear_flags)
  self
end
clear_start() click to toggle source

Clear any start set bits back to 0

# File lib/origen/registers/bit_collection.rb, line 876
def clear_start
  each(&:clear_start)
  self
end
clear_w1c() click to toggle source

Clear any w1c set bits back to 0

# File lib/origen/registers/bit_collection.rb, line 870
def clear_w1c
  each(&:clear_w1c)
  self
end
clr_only(value) click to toggle source

Modify clr_only for bits in collection

# File lib/origen/registers/bit_collection.rb, line 851
def clr_only(value)
  shift_out_with_index { |bit, i| bit.clr_only = (value[i] == 0b1) }
  self
end
contains_bits?() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 318
def contains_bits?
  true
end
copy_all(reg) click to toggle source

Copies all data and flags from one bit collection (or reg) object to another

This method will accept a dumb value as the argument, in which case it is essentially a write, however it will also clear all flags.

# File lib/origen/registers/bit_collection.rb, line 215
def copy_all(reg)
  if reg.respond_to?(:contains_bits?) && reg.contains_bits?
    unless reg.size == size
      puts 'Bit collection copy must be performed on collections of the same size.'
      puts 'You can fix this by calling copy on a subset of the bits you require, e.g.'
      puts '  larger_bit_collection[3..0].copy_all(smaller_bit_collection)'
      puts
      fail 'Mismatched size for bit collection copy'
    end
    # safely handle collections with differing with_bit_order settings
    with_lsb0 do
      reg.shift_out_with_index do |source_bit, i|
        if source_bit
          self[i].overlay(source_bit.overlay_str) if source_bit.has_overlay?
          self[i].write(source_bit.data)

          self[i].read if source_bit.is_to_be_read?
          self[i].store if source_bit.is_to_be_stored?
        end
      end
    end # of with_lsb0
  else
    write(reg)
    clear_flags
  end
  self
end
data() click to toggle source

Returns the data value held by the collection

Example

reg(:control).write(0x55)
reg(:control).data         #  => 0x55, assuming the reg has the required bits to store that
# File lib/origen/registers/bit_collection.rb, line 335
def data
  data = 0
  shift_out_with_index do |bit, i|
    return undefined if bit.is_a?(Origen::UndefinedClass)

    data |= bit.data << i
  end
  data
end
Also aliased as: val, value
data=(value, options = {})
Alias for: write
data_b() click to toggle source

Returns the inverse of the data value held by the collection

# File lib/origen/registers/bit_collection.rb, line 348
def data_b
  # (& operation takes care of Bignum formatting issues)
  ~data & ((1 << size) - 1)
end
data_reverse() click to toggle source

Returns the reverse of the data value held by the collection

# File lib/origen/registers/bit_collection.rb, line 354
def data_reverse
  data = 0
  reverse_shift_out_with_index do |bit, i|
    return undefined if bit.is_a?(Origen::UndefinedClass)

    data |= bit.data << i
  end
  data
end
Also aliased as: reverse_data
delete() click to toggle source

Delete the contained bits from the parent Register

# File lib/origen/registers/bit_collection.rb, line 712
def delete
  @reg.delete_bits(self)
  self
end
description(bitname = nil, options = {}) click to toggle source

Returns the description of the given bit(s) if any, if none then an empty array will be returned

Note Adding a description field will override any comment-driven documentation of a bit collection (ie markdown style comments)

# File lib/origen/registers/bit_collection.rb, line 274
def description(bitname = nil, options = {})
  bitname, options = nil, bitname if bitname.is_a?(Hash)
  if name == :unknown
    []
  else
    @reg.description(name, options)
  end
end
enable_mask(operation) click to toggle source

Returns a value representing the bit collection / register where a bit value of 1 means the bit is enabled for the given operation.

# File lib/origen/registers/bit_collection.rb, line 429
def enable_mask(operation)
  str = ''
  shift_out_left do |bit|
    if operation == :store && bit.is_to_be_stored? ||
       operation == :read && bit.is_to_be_read? ||
       operation == :overlay && bit.has_overlay?
      str += '1'
    else
      str += '0'
    end
  end
  str.to_i(2)
end
enabled?() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 834
def enabled?
  all?(&:enabled?)
end
enabled_by_feature?(name = nil)
feature() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 802
def feature
  feature = []
  feature << fetch(0).feature
  each { |bit| feature << bit.feature if bit.has_feature_constraint? }
  feature = feature.flatten.uniq unless feature.empty?
  feature.delete(nil) if feature.include?(nil)
  if !feature.empty?
    if feature.size == 1
      feature[0]
    else
      feature.uniq
    end
  else
    if Origen.config.strict_errors
      fail 'No feature found'
    end

    nil
  end
end
Also aliased as: features
features()
Alias for: feature
full_name(bitname = nil, options = {}) click to toggle source
# File lib/origen/registers/bit_collection.rb, line 283
def full_name(bitname = nil, options = {})
  bitname, options = nil, bitname if bitname.is_a?(Hash)
  unless name == :unknown
    @reg.full_name(name, options)
  end
end
has_feature_constraint?(name = nil) click to toggle source

Return true if there is any feature associated with these bits

# File lib/origen/registers/bit_collection.rb, line 825
def has_feature_constraint?(name = nil)
  if !name
    any?(&:has_feature_constraint?)
  else
    any? { |bit| bit.enabled_by_feature?(name) }
  end
end
Also aliased as: enabled_by_feature?
has_known_value?() click to toggle source

Returns true if the values of all bits in the collection are known. The value will be unknown in cases where the reset value is undefined or determined by a memory location and where the register has not been written or read to a specific value yet.

# File lib/origen/registers/bit_collection.rb, line 757
def has_known_value?
  all?(&:has_known_value?)
end
has_overlay?(name = nil) click to toggle source

Returns true if any bits within are tagged for overlay, supply a specific name to require a specific overlay only

Example

myreg.overlay("data")
myreg.has_overlay?              # => true
myreg.has_overlay?("address")   # => false
myreg.has_overlay?("data")      # => true
# File lib/origen/registers/bit_collection.rb, line 550
def has_overlay?(name = nil)
  any? { |bit| bit.has_overlay?(name) }
end
inspect() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 322
def inspect
  "<#{self.class}:#{object_id}>"
end
is_readable?() click to toggle source

Returns true if any bits in the collection are readable

# File lib/origen/registers/bit_collection.rb, line 845
def is_readable?
  any?(&:readable?)
end
Also aliased as: readable?
is_to_be_read?() click to toggle source

Returns true if any bits have the read flag set - see Bit#is_to_be_read? for more details.

# File lib/origen/registers/bit_collection.rb, line 511
def is_to_be_read?
  any?(&:is_to_be_read?)
end
is_to_be_stored?() click to toggle source

Returns true if any bits have the store flag set - see Bit#is_to_be_stored? for more details.

# File lib/origen/registers/bit_collection.rb, line 517
def is_to_be_stored?
  any?(&:is_to_be_stored?)
end
is_writable?() click to toggle source

Returns true if any bits in the collection are writable

# File lib/origen/registers/bit_collection.rb, line 839
def is_writable?
  any?(&:writable?)
end
Also aliased as: writable?
nvm_dep() click to toggle source

Return nvm_dep value held by collection

# File lib/origen/registers/bit_collection.rb, line 863
def nvm_dep
  nvm_dep = 0
  shift_out_with_index { |bit, i| nvm_dep |= bit.nvm_dep << i }
  nvm_dep
end
overlay(value) click to toggle source

Attaches the supplied overlay string to all bits

Example

reg(:data).overlay(“data_val”)

# File lib/origen/registers/bit_collection.rb, line 446
def overlay(value)
  each { |bit| bit.overlay(value) }
  self
end
overlay_str() click to toggle source

Cycles through all bits and returns the last overlay value found, it is assumed therefore that all bits have the same overlay value when calling this method

Example

myreg.overlay("data")

myreg.overlay_str   # => "data"
# File lib/origen/registers/bit_collection.rb, line 560
def overlay_str
  result = ''
  each do |bit|
    result = bit.overlay_str if bit.has_overlay?
  end
  result.to_s
end
owner() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 726
def owner
  first.owner
end
parent() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 108
def parent
  @reg
end
path_var() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 112
def path_var
  if first.path_var
    if first.path_var =~ /^\./
      base = parent.path(relative_to: parent.parent)
      "#{base}#{first.path_var}"
    else
      first.path_var
    end
  else
    base = parent.path(relative_to: parent.parent)
    if size == 1
      "#{base}[#{position}]"
    else
      "#{base}[#{position + size - 1}:#{position}]"
    end
  end
end
position() click to toggle source

Returns the LSB position of the collection

# File lib/origen/registers/bit_collection.rb, line 327
def position
  first.position
end
preserve_flags() { || ... } click to toggle source

At the end of the given block, the status flags of all bits will be restored to the state that they were upon entry to the block

# File lib/origen/registers/bit_collection.rb, line 195
def preserve_flags
  orig = []
  each do |bit|
    orig << [bit.overlay_str, bit.is_to_be_read?, bit.is_to_be_stored?]
  end
  yield
  each do |bit|
    bit.clear_flags
    flags = orig.shift
    bit.overlay(flags[0])
    bit.read if flags[1]
    bit.store if flags[2]
  end
  self
end
read!(value = nil, options = {}) { |size == size ? reg : self| ... } click to toggle source

Similar to write! this method will perform the standard read method and then make a call to $top.read_register(self) with the expectation that this method will implement a read event in the pattern.

Example

reg(:data).read!         # Read register :data, expecting whatever value it currently holds
reg(:data).read!(0x5555) # Read register :data, expecting 0x5555
# File lib/origen/registers/bit_collection.rb, line 588
def read!(value = nil, options = {})
  value, options = nil, value if value.is_a?(Hash)
  read(value, options) unless block_given?
  if block_given?
    yield size == @reg.size ? @reg : self
  end
  @reg.request(:read_register, options)
  self
end
Also aliased as: assert!
readable(value) click to toggle source

Modify readable for bits in collection

# File lib/origen/registers/bit_collection.rb, line 797
def readable(value)
  shift_out_with_index { |bit, i| bit.readable = (value[i] == 0b1); bit.set_access_from_rw }
  self
end
readable?()
Alias for: is_readable?
reset() click to toggle source

Resets all bits, this clears all flags and assigns the data value back to the reset state

# File lib/origen/registers/bit_collection.rb, line 453
def reset
  each(&:reset)
  self
end
reset_data(value = nil) click to toggle source

Returns the reset value of the collection, note that this does not reset the register and the current data is maintained.

Example

reg(:control).write(0x55)
reg(:control).data         #  => 0x55
reg(:control).reset_data   #  => 0x11, assuming the reg was declared with a reset value of 0x11
reg(:control).data         #  => 0x55
# File lib/origen/registers/bit_collection.rb, line 769
def reset_data(value = nil)
  # This method was originally setup to set the reset value by passing an argument
  if value
    shift_out_with_index { |bit, i| bit.reset_val = value[i] }
    self
  else
    data = 0
    shift_out_with_index do |bit, i|
      return bit.reset_data if bit.reset_data.is_a?(Symbol)

      data |= bit.reset_data << i
    end
    data
  end
end
reset_data=(value = nil)
Alias for: reset_data
reset_val(value = nil)
Alias for: reset_data
reset_val=(value = nil)
Alias for: reset_data
reset_value(value = nil)
Alias for: reset_data
reset_value=(value = nil)
Alias for: reset_data
reverse_data()
Alias for: data_reverse
reverse_shift_out(&block) click to toggle source

Yields each bit in the register, MSB first.

# File lib/origen/registers/bit_collection.rb, line 500
def reverse_shift_out(&block)
  reverse_each(&block)
end
reverse_shift_out_with_index(&block) click to toggle source

Yields each bit in the register and its index, MSB first.

# File lib/origen/registers/bit_collection.rb, line 505
def reverse_shift_out_with_index(&block)
  reverse_each.with_index(&block)
end
set_only(value) click to toggle source

Modify set_only for bits in collection

# File lib/origen/registers/bit_collection.rb, line 857
def set_only(value)
  shift_out_with_index { |bit, i| bit.set_only = (value[i] == 0b1) }
  self
end
setting(value) click to toggle source

Returns the value you would need to write to the register to put the given value in these bits

# File lib/origen/registers/bit_collection.rb, line 535
def setting(value)
  result = 0
  shift_out_with_index do |bit, i|
    result |= bit.setting(value[i])
  end
  result
end
shift_left(data = 0) click to toggle source

Shifts the data in the collection left by one place. The data held by the rightmost bit will be set to the given value (0 by default).

@example

myreg.data          # => 0b1111
myreg.shift_left
myreg.data          # => 0b1110
myreg.shift_left
myreg.data          # => 0b1100
myreg.shift_left(1)
myreg.data          # => 0b1001
myreg.shift_left(1)
myreg.data          # => 0b0011
# File lib/origen/registers/bit_collection.rb, line 961
def shift_left(data = 0)
  prev_bit = nil
  reverse_shift_out do |bit|
    prev_bit.write(bit.data) if prev_bit
    prev_bit = bit
  end
  prev_bit.write(data)
  self
end
shift_out(&block) click to toggle source

Yields each bit in the register, LSB first.

# File lib/origen/registers/bit_collection.rb, line 490
def shift_out(&block)
  each(&block)
end
shift_out_left() { |bit| ... } click to toggle source

Shifts out a stream of bit objects corresponding to the size of the BitCollection. i.e. calling this on a 16-bit register this will pass back 16 bit objects. If there are holes in the given register then a dummy bit object will be returned that is not writable and which will always read as 0.

Example

reg(:data).shift_out_left do |bit|
    bist_shift(bit)
end
# File lib/origen/registers/bit_collection.rb, line 466
def shift_out_left
  # This is functionally equivalent to reverse_shift_out
  reverse_each { |bit| yield bit }
end
shift_out_left_with_index() { |bit, i| ... } click to toggle source

Same as Reg#shift_out_left but includes the index counter

# File lib/origen/registers/bit_collection.rb, line 472
def shift_out_left_with_index
  # This is functionally equivalent to reverse_shift_out_with_index
  reverse_each.with_index { |bit, i| yield bit, i }
end
shift_out_right() { |bit| ... } click to toggle source

Same as Reg#shift_out_left but starts from the LSB

# File lib/origen/registers/bit_collection.rb, line 478
def shift_out_right
  # This is functionally equivalent to shift_out, actually sends LSB first
  each { |bit| yield bit }
end
shift_out_right_with_index() { |bit, i| ... } click to toggle source

Same as Reg#shift_out_right but includes the index counter

# File lib/origen/registers/bit_collection.rb, line 484
def shift_out_right_with_index
  # This is functionally equivalent to shift_out_with_index
  each_with_index { |bit, i| yield bit, i }
end
shift_out_with_index(&block) click to toggle source

Yields each bit in the register and its index, LSB first.

# File lib/origen/registers/bit_collection.rb, line 495
def shift_out_with_index(&block)
  each_with_index(&block)
end
shift_right(data = 0) click to toggle source

Shifts the data in the collection right by one place. The data held by the leftmost bit will be set to the given value (0 by default).

@example

myreg.data          # => 0b1111
myreg.shift_right
myreg.data          # => 0b0111
myreg.shift_right
myreg.data          # => 0b0011
myreg.shift_right(1)
myreg.data          # => 0b1001
myreg.shift_right(1)
myreg.data          # => 0b1100
# File lib/origen/registers/bit_collection.rb, line 984
def shift_right(data = 0)
  prev_bit = nil
  shift_out do |bit|
    prev_bit.write(bit.data) if prev_bit
    prev_bit = bit
  end
  prev_bit.write(data)
  self
end
status_str(operation, options = {}) click to toggle source

Provides a string summary of the bit collection / register state that would be applied to given operation (write or read). This is mainly intended to be useful when generating pattern comments describing an upcoming register transaction.

This highlights not only bit values bit the status of any flags or overlays that are currently set.

The data is presented in hex nibble format with individual nibbles are expanded to binary format whenever all 4 bits do not have the same status - e.g. if only one of the four is marked for read.

The following symbols are used to represent bit state:

X - Bit is don’t care (not marked for read) V - Bit has been tagged with an overlay S - Bit is marked for store

@example

myreg.status_str(:write)   # => "0000"
myreg.status_str(:read)    # => "XXXX"
myreg[7..4].read(5)
myreg.status_str(:read)    # => "XX5X"
myreg[14].read(0)
myreg.status_str(:read)    # => "(x0xx)X5X"
# File lib/origen/registers/bit_collection.rb, line 907
def status_str(operation, options = {})
  options = {
    mark_overlays: true
  }.merge(options)
  str = ''
  if operation == :read
    shift_out_left do |bit|
      if bit.is_to_be_stored?
        str += STORE_CHAR
      elsif bit.is_to_be_read?
        if bit.has_overlay? && options[:mark_overlays]
          str += OVERLAY_CHAR
        else
          if bit.has_known_value?
            str += bit.data.to_s
          else
            str += UNKNOWN_CHAR
          end
        end
      else
        str += DONT_CARE_CHAR
      end
    end
  elsif operation == :write
    shift_out_left do |bit|
      if bit.has_overlay? && options[:mark_overlays]
        str += OVERLAY_CHAR
      else
        if bit.has_known_value?
          str += bit.data.to_s
        else
          str += UNKNOWN_CHAR
        end
      end
    end
  else
    fail "Unknown operation (#{operation}), must be :read or :write"
  end
  make_hex_like(str, (size / 4.0).ceil)
end
sticky_overlay(set = true) click to toggle source

Normally whenever a register is processed by the $top.read_register method it will call Reg#clear_flags to acknowledge that the read has been performed, which clears the read and store flags for the given bits. Normally however you want overlays to stick around such that whenever a given bit is written/read its data is always picked from an overlay.
Call this passing in false for a given register to cause the overlay data to also be cleared by Reg#clear_flags.

Example

reg(:data).overlay("data_val")
reg(:data).has_overlay?           # => true
reg(:data).clear_flags
reg(:data).has_overlay?           # => true
reg(:data).sticky_overlay(false)
reg(:data).clear_flags
reg(:data).has_overlay?           # => false
# File lib/origen/registers/bit_collection.rb, line 614
def sticky_overlay(set = true)
  each { |bit| bit.sticky_overlay = set }
  self
end
Also aliased as: sticky_overlays
sticky_overlays(set = true)
Alias for: sticky_overlay
sticky_store(set = true) click to toggle source

Similar to sticky_overlay this method affects how the store flags are treated by Reg#clear_flags.
The default is that store flags will get cleared by Reg#clear_flags, passing true into this method will override this and prevent them from clearing.

Example

reg(:data).sticky_store(true)
reg(:data).store
reg(:data).clear_flags         # Does not clear the request to store
# File lib/origen/registers/bit_collection.rb, line 628
def sticky_store(set = true)
  each { |bit| bit.sticky_store = set }
  self
end
store(options = {}) click to toggle source

Marks all bits to be stored

# File lib/origen/registers/bit_collection.rb, line 634
def store(options = {})
  each(&:store)
  self
end
store!(options = {}) click to toggle source

Marks all bits to be stored and then calls read!

# File lib/origen/registers/bit_collection.rb, line 640
def store!(options = {})
  store(options)
  read!(options)
  self
end
store_overlay_bits(options = {}) click to toggle source

Sets the store flag on all bits that already have the overlay flag set

# File lib/origen/registers/bit_collection.rb, line 656
def store_overlay_bits(options = {})
  # Pass in an array of any overlays that are to be excluded from store
  options = { exclude: [] }.merge(options)
  each do |bit|
    bit.store if bit.has_overlay? && !options[:exclude].include?(bit.overlay_str)
  end
  self
end
store_overlay_bits!(options = {}) click to toggle source

Sets the store flag on all bits that already have the overlay flag set and then calls $top.read_register passing self as the first argument

# File lib/origen/registers/bit_collection.rb, line 648
def store_overlay_bits!(options = {})
  store_overlay_bits(options)
  @reg.request(:read_register, options) # Bypass the normal read method since we don't want to
  # tag the other bits for read
  self
end
sync(size = nil, options = {}) click to toggle source

Update the register contents with the live value from the device under test.

The current tester needs to be an OrigenLink driver. Upon calling this method a request will be made to read the given register, the read data will be captured and the register model will be updated.

The register parent register object is returned, this means that calling .sync on a register or bitcollection object will automatically update it and the display the register in the console.

Normally this method should be called from a breakpoint during pattern debug, and it is not intended to be inserted into production pattern logic.

# File lib/origen/registers/bit_collection.rb, line 152
def sync(size = nil, options = {})
  size, options = nil, size if size.is_a?(Hash)
  if tester.respond_to?(:capture)
    preserve_flags do
      v = tester.capture do
        store!(sync: true)
      end
      if v.first
        # Serial shift
        if v.size == 1
          reverse_shift_out_with_index do |bit, i|
            bit.instance_variable_set('@updated_post_reset', true)
            bit.instance_variable_set('@data', v.first[i])
          end
        # Parallel shift
        else
          reverse_shift_out_with_index do |bit, i|
            bit.instance_variable_set('@updated_post_reset', true)
            bit.instance_variable_set('@data', v[i].to_i)
          end
        end
      else
        Origen.log.warning "No data was captured when attempting to sync register #{owner.name}, this is probably because the current read_register driver method does not implement store requests"
      end
    end
    if size
      puts "#{parent.address.to_s(16).upcase}: " + data.to_s(16).upcase.rjust(Origen.top_level.memory_width / 4, '0')
      if size > 1
        step = Origen.top_level.memory_width / 8
        Origen.top_level.mem(parent.address + step).sync(size - 1)
      end
      nil
    else
      parent
    end
  else
    Origen.log.warning 'Sync is not supported on the current tester driver, register not updated'
  end
end
Also aliased as: sync!
sync!(size = nil, options = {})
Alias for: sync
terminal?() click to toggle source
# File lib/origen/registers/bit_collection.rb, line 63
def terminal?
  true
end
unique_overlays() { |current_overlay, length, data| ... } click to toggle source

Will yield all unique overlay strings attached to the bits within the collection. It will also return the number of bits for the overlay (the length) and the current data value held in those bits.

Example

reg(:control).unique_overlays do |str, length, data|
    do_something(str, length, data)
end
# File lib/origen/registers/bit_collection.rb, line 672
def unique_overlays
  current_overlay = false
  length = 0
  data = 0
  shift_out_right do |bit|
    # Init the current overlay when the first one is encountered
    current_overlay = bit.overlay_str if bit.has_overlay? && !current_overlay

    if bit.has_overlay?
      if bit.overlay_str != current_overlay
        yield current_overlay, length, data if current_overlay
        length = 0
        data = 0
      end

      data = data | (bit.data << length)
      length += 1
    else
      yield current_overlay, length, data if current_overlay
      length = 0
      data = 0
      current_overlay = false
    end
  end
  yield current_overlay, length, data if current_overlay
end
unknown=(val) click to toggle source

Sets the unknown attribute on all contained bits

# File lib/origen/registers/bit_collection.rb, line 401
def unknown=(val)
  each { |bit| bit.unknown = val }
end
update_required?() click to toggle source

Returns true if any bits have the update_required flag set - see Bit#update_required? for more details.

# File lib/origen/registers/bit_collection.rb, line 523
def update_required?
  any?(&:update_required?)
end
val()
Alias for: data
val=(value, options = {})
Alias for: write
value()
Alias for: data
value=(value, options = {})
Alias for: write
whole_reg?() click to toggle source

Returns true if the collection contains all bits in the register

# File lib/origen/registers/bit_collection.rb, line 374
def whole_reg?
  size == parent.size
end
with_bit_order() click to toggle source

Returns the bit numbering order to use when interpreting indeces

# File lib/origen/registers/bit_collection.rb, line 39
def with_bit_order
  @with_bit_order
end
with_lsb0() { || ... } click to toggle source

Allow bit number interpreting to be explicitly set to lsb0

# File lib/origen/registers/bit_collection.rb, line 50
def with_lsb0
  if block_given?
    # run just the code block with lsb0 numbering (for internal methods)
    saved_wbo = @with_bit_order
    @with_bit_order = :lsb0
    yield
    @with_bit_order = saved_wbo
  else
    @with_bit_order = :lsb0
    self
  end
end
with_msb0() click to toggle source

Allow bit number interpreting to be explicitly set to msb0

# File lib/origen/registers/bit_collection.rb, line 44
def with_msb0
  @with_bit_order = :msb0
  self
end
writable(value) click to toggle source

Modify writable for bits in collection

# File lib/origen/registers/bit_collection.rb, line 791
def writable(value)
  shift_out_with_index { |bit, i| bit.writable = (value[i] == 0b1); bit.set_access_from_rw }
  self
end
writable?()
Alias for: is_writable?
write(value, options = {}) click to toggle source

Set the data value of the collection within the patgen, but not on silicon - i.e. calling write will not trigger a pattern write event.

# File lib/origen/registers/bit_collection.rb, line 380
def write(value, options = {})
  # If an array is written it means a data value and an overlay have been supplied
  # in one go...
  if value.is_a?(Array) && !value.is_a?(BitCollection)
    overlay(value[1])
    value = value[0]
  end
  value = value.data if value.respond_to?('data')

  with_lsb0 do
    size.times do |i|
      self[i].write(value[i], options)
    end
  end
  self
end
Also aliased as: data=, value=, val=
write!(value = nil, options = {}) { |size == size ? reg : self| ... } click to toggle source

Write the bit value on silicon. This method will update the data value of the bits and then call $top.write_register passing the owning register as the first argument. This method is expected to handle writing the current state of the register to silicon.

# File lib/origen/registers/bit_collection.rb, line 572
def write!(value = nil, options = {})
  value, options = nil, value if value.is_a?(Hash)
  write(value, options) if value
  if block_given?
    yield size == @reg.size ? @reg : self
  end
  @reg.request(:write_register, options)
  self
end

Private Instance Methods

expand_and_order(*indexes) click to toggle source

Cleans up indexed references to pins, e.g. makes these equal:

bits(:data)[0,1,2,3]
bits(:data)[3,2,1,0]
bits(:data)[0..3]
bits(:data)[3..0]
# File lib/origen/registers/bit_collection.rb, line 1035
def expand_and_order(*indexes)
  ixs = []
  indexes.flatten.each do |index|
    if index.is_a?(Range)
      if index.first > index.last
        ixs << (index.last..index.first).to_a
      else
        ixs << index.to_a
      end
    else
      ixs << index
    end
  end
  ixs.flatten!
  # ixs.sort!
  # convert msb0 numbering (if provided) to lsb0 numbering to get the correct bits
  if @with_bit_order == :msb0
    ixs.each_index { |i| ixs[i] = size - ixs[i] - 1 }
  end
  ixs.sort
end
make_hex_like(regval, size_in_nibbles) click to toggle source

Converts a binary-like representation of a data value into a hex-like version. e.g. input => 010S0011SSSS0110 (where S, X or V represent store, don’t care or overlay)

output => [010s]3S6    (i.e. nibbles that are not all of the same type are expanded)
# File lib/origen/registers/bit_collection.rb, line 999
def make_hex_like(regval, size_in_nibbles)
  outstr = ''
  regex = '^(.?.?.?.)'
  (size_in_nibbles - 1).times { regex += '(....)' }
  regex += '$'
  Regexp.new(regex) =~ regval

  nibbles = []
  size_in_nibbles.times do |n| # now grouped by nibble
    nibbles << Regexp.last_match[n + 1]
  end

  nibbles.each_with_index do |nibble, i|
    # If contains any special chars...
    if nibble =~ /[#{UNKNOWN_CHAR}#{DONT_CARE_CHAR}#{STORE_CHAR}#{OVERLAY_CHAR}]/
      # If all the same...
      if nibble[0] == nibble[1] && nibble[1] == nibble[2] && nibble[2] == nibble[3]
        outstr += nibble[0, 1] # .to_s
      # Otherwise present this nibble in 'binary' format
      else
        outstr += "[#{nibble.downcase}]"
      end
    # Otherwise if all 1s and 0s...
    else
      outstr += '%1X' % nibble.to_i(2)
    end
  end
  outstr
end