Class: Origen::Registers::BitCollection
- Includes:
- Netlist::Connectable, SubBlocks::Path
- Defined in:
- lib/origen/registers/bit_collection.rb
Overview
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 - http://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.
Direct Known Subclasses
Constant Summary collapse
- DONT_CARE_CHAR =
'X'- OVERLAY_CHAR =
'V'- STORE_CHAR =
'S'- UNKNOWN_CHAR =
'?'
Instance Attribute Summary collapse
-
#name ⇒ Object
(also: #id)
Returns the value of attribute name.
Class Method Summary collapse
-
.dummy(reg, name = nil, options = {}) ⇒ Object
Returns a dummy bit collection that is populated with un-writable bits that will read back as 0.
Instance Method Summary collapse
-
#[](*indexes) ⇒ Object
(also: #bits, #bit)
Access bits by index.
- #abs_path ⇒ Object
-
#access(value = nil) ⇒ Object
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.
-
#access! ⇒ Object
Like access but will raise an error if not all bits in the collection have the same access value.
-
#add_name(name) ⇒ Object
:nodoc:.
-
#append_overlays(value) ⇒ Object
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".
- #bind(live_parameter) ⇒ Object
-
#bit_order ⇒ Object
Returns the bit order of the parent register.
- #bit_value_descriptions(_bitname = nil) ⇒ Object
-
#clear_flags ⇒ Object
Calls the clear_flags method on all bits, see Bit#clear_flags for more details.
-
#clear_start ⇒ Object
Clear any start set bits back to 0.
-
#clear_w1c ⇒ Object
Clear any w1c set bits back to 0.
-
#clr_only(value) ⇒ Object
Modify clr_only for bits in collection.
- #contains_bits? ⇒ Boolean
-
#copy_all(reg) ⇒ Object
Copies all data and flags from one bit collection (or reg) object to another.
-
#data ⇒ Object
(also: #val, #value)
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.
-
#data_b ⇒ Object
Returns the inverse of the data value held by the collection.
-
#data_reverse ⇒ Object
(also: #reverse_data)
Returns the reverse of the data value held by the collection.
-
#delete ⇒ Object
Delete the contained bits from the parent Register.
-
#description(bitname = nil, options = {}) ⇒ Object
Returns the description of the given bit(s) if any, if none then an empty array will be returned.
-
#enable_mask(operation) ⇒ Object
Returns a value representing the bit collection / register where a bit value of 1 means the bit is enabled for the given operation.
- #enabled? ⇒ Boolean
- #feature ⇒ Object (also: #features)
- #full_name(bitname = nil, options = {}) ⇒ Object
-
#has_feature_constraint?(name = nil) ⇒ Boolean
(also: #enabled_by_feature?)
Return true if there is any feature associated with these bits.
-
#has_known_value? ⇒ Boolean
Returns true if the values of all bits in the collection are known.
-
#has_overlay?(name = nil) ⇒ Boolean
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.
-
#initialize(reg, name, data = [], options = {}) ⇒ BitCollection
constructor
:nodoc:.
- #inspect ⇒ Object
-
#is_readable? ⇒ Boolean
(also: #readable?)
Returns true if any bits in the collection are readable.
-
#is_to_be_read? ⇒ Boolean
Returns true if any bits have the read flag set - see Bit#is_to_be_read? for more details.
-
#is_to_be_stored? ⇒ Boolean
Returns true if any bits have the store flag set - see Bit#is_to_be_stored? for more details.
-
#is_writable? ⇒ Boolean
(also: #writable?)
Returns true if any bits in the collection are writable.
-
#method_missing(method, *args, &block) ⇒ Object
All other methods send to bit 0.
-
#nvm_dep ⇒ Object
Return nvm_dep value held by collection.
-
#overlay(value) ⇒ Object
Attaches the supplied overlay string to all bits ==== Example reg(:data).overlay("data_val").
-
#overlay_str ⇒ Object
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").
- #owner ⇒ Object
- #parent ⇒ Object
- #path_var ⇒ Object
-
#position ⇒ Object
Returns the LSB position of the collection.
-
#preserve_flags ⇒ Object
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.
-
#read(value = nil, options = {}) ⇒ Object
(also: #assert)
Will tag all bits for read and if a data value is supplied it will update the expected data for when the read is performed.
-
#read!(value = nil, options = {}) ⇒ Object
(also: #assert!)
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.
-
#readable(value) ⇒ Object
Modify readable for bits in collection.
-
#reset ⇒ Object
Resets all bits, this clears all flags and assigns the data value back to the reset state.
-
#reset_data(value = nil) ⇒ Object
(also: #reset_val, #reset_value, #reset_data=, #reset_val=, #reset_value=)
Returns the reset value of the collection, note that this does not reset the register and the current data is maintained.
-
#respond_to?(*args) ⇒ Boolean
Recognize that BitCollection responds to some Bit methods via method_missing.
-
#reverse_shift_out(&block) ⇒ Object
Yields each bit in the register, MSB first.
-
#reverse_shift_out_with_index(&block) ⇒ Object
Yields each bit in the register and its index, MSB first.
-
#set_only(value) ⇒ Object
Modify set_only for bits in collection.
-
#setting(value) ⇒ Object
Returns the value you would need to write to the register to put the given value in these bits.
-
#shift_left(data = 0) ⇒ Object
Shifts the data in the collection left by one place.
-
#shift_out(&block) ⇒ Object
Yields each bit in the register, LSB first.
-
#shift_out_left ⇒ Object
Shifts out a stream of bit objects corresponding to the size of the BitCollection.
-
#shift_out_left_with_index ⇒ Object
Same as Reg#shift_out_left but includes the index counter.
-
#shift_out_right ⇒ Object
Same as Reg#shift_out_left but starts from the LSB.
-
#shift_out_right_with_index ⇒ Object
Same as Reg#shift_out_right but includes the index counter.
-
#shift_out_with_index(&block) ⇒ Object
Yields each bit in the register and its index, LSB first.
-
#shift_right(data = 0) ⇒ Object
Shifts the data in the collection right by one place.
-
#status_str(operation, options = {}) ⇒ Object
Provides a string summary of the bit collection / register state that would be applied to given operation (write or read).
-
#sticky_overlay(set = true) ⇒ Object
(also: #sticky_overlays)
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.
-
#sticky_store(set = true) ⇒ Object
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. -
#store(options = {}) ⇒ Object
Marks all bits to be stored.
-
#store!(options = {}) ⇒ Object
Marks all bits to be stored and then calls read!.
-
#store_overlay_bits(options = {}) ⇒ Object
Sets the store flag on all bits that already have the overlay flag set.
-
#store_overlay_bits!(options = {}) ⇒ Object
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.
-
#sync(size = nil, options = {}) ⇒ Object
(also: #sync!)
Update the register contents with the live value from the device under test.
- #terminal? ⇒ Boolean
-
#unique_overlays {|current_overlay, length, data| ... } ⇒ Object
Will yield all unique overlay strings attached to the bits within the collection.
-
#unknown=(val) ⇒ Object
Sets the unknown attribute on all contained bits.
-
#update_required? ⇒ Boolean
Returns true if any bits have the update_required flag set - see Bit#update_required? for more details.
-
#whole_reg? ⇒ Boolean
Returns true if the collection contains all bits in the register.
-
#with_bit_order ⇒ Object
Returns the bit numbering order to use when interpreting indeces.
-
#with_lsb0 ⇒ Object
Allow bit number interpreting to be explicitly set to lsb0.
-
#with_msb0 ⇒ Object
Allow bit number interpreting to be explicitly set to msb0.
-
#writable(value) ⇒ Object
Modify writable for bits in collection.
-
#write(value, options = {}) ⇒ Object
(also: #data=, #value=, #val=)
Set the data value of the collection within the patgen, but not on silicon - i.e.
-
#write!(value = nil, options = {}) ⇒ Object
Write the bit value on silicon.
Methods included from Netlist::Connectable
Methods included from SubBlocks::Path
Methods inherited from Array
#dups, #dups?, #dups_with_index, #ids, #include_hash?, #include_hash_with_key?
Constructor Details
#initialize(reg, name, data = [], options = {}) ⇒ BitCollection
:nodoc:
23 24 25 26 27 28 29 30 31 |
# File 'lib/origen/registers/bit_collection.rb', line 23 def initialize(reg, name, data = [], = {}) # :nodoc: if reg.respond_to?(:has_bits_enabled_by_feature?) && reg.has_parameter_bound_bits? reg.update_bound_bits unless reg.updating_bound_bits? end @reg = reg @name = name @with_bit_order = [:with_bit_order] || :lsb0 [data].flatten.each { |item| self << item } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
All other methods send to bit 0
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
# File 'lib/origen/registers/bit_collection.rb', line 728 def method_missing(method, *args, &block) # :nodoc: if first.respond_to?(method) if size > 1 if [:meta, :meta_data, :metadata].include?(method.to_sym) || first.(method) first.send(method, *args, &block) else fail "Error, calling #{method} on a multi-bit collection is not implemented!" end else first.send(method, *args, &block) end else fail "BitCollection does not have a method named #{method}!" end end |
Instance Attribute Details
#name ⇒ Object Also known as: id
Returns the value of attribute name.
20 21 22 |
# File 'lib/origen/registers/bit_collection.rb', line 20 def name @name end |
Class Method Details
.dummy(reg, name = nil, options = {}) ⇒ Object
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.
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/origen/registers/bit_collection.rb', line 302 def self.dummy(reg, name = nil, = {}) name, = nil, name if name.is_a?(Hash) = { size: 8, pos: 0 }.merge() collection = new(reg, name) pos = [:pos] [:size].times do bit = Bit.new(reg, pos, writable: false, feature: :dummy_feature) collection << bit pos += 1 end collection end |
Instance Method Details
#[](*indexes) ⇒ Object Also known as: bits, bit
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 # 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
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/origen/registers/bit_collection.rb', line 89 def [](*indexes) return self if indexes.empty? b = BitCollection.new(parent, name) (*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 |
#abs_path ⇒ Object
130 131 132 |
# File 'lib/origen/registers/bit_collection.rb', line 130 def abs_path first.abs_path end |
#access(value = nil) ⇒ Object
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
249 250 251 252 253 254 255 256 |
# 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! ⇒ Object
Like access but will raise an error if not all bits in the collection have the same access value
260 261 262 263 264 265 266 267 |
# 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 |
#add_name(name) ⇒ Object
:nodoc:
714 715 716 717 718 719 720 721 |
# File 'lib/origen/registers/bit_collection.rb', line 714 def add_name(name) # :nodoc: if @name == :unknown @name = name elsif ![name].flatten.include?(name) @name = [@name, name].flatten end self end |
#append_overlays(value) ⇒ Object
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"
701 702 703 704 705 706 |
# File 'lib/origen/registers/bit_collection.rb', line 701 def (value) each do |bit| bit.(bit. + value) if bit. end self end |
#bind(live_parameter) ⇒ Object
67 68 69 |
# File 'lib/origen/registers/bit_collection.rb', line 67 def bind(live_parameter) parent.bind(name, live_parameter) end |
#bit_order ⇒ Object
Returns the bit order of the parent register
34 35 36 |
# File 'lib/origen/registers/bit_collection.rb', line 34 def bit_order parent.bit_order end |
#bit_value_descriptions(_bitname = nil) ⇒ Object
290 291 292 293 294 295 296 297 |
# File 'lib/origen/registers/bit_collection.rb', line 290 def bit_value_descriptions(_bitname = nil) = _bitname.is_a?(Hash) ? _bitname : {} if name == :unknown [] else @reg.bit_value_descriptions(name, ) end end |
#clear_flags ⇒ Object
Calls the clear_flags method on all bits, see Bit#clear_flags for more details
525 526 527 528 |
# File 'lib/origen/registers/bit_collection.rb', line 525 def clear_flags each(&:clear_flags) self end |
#clear_start ⇒ Object
Clear any start set bits back to 0
873 874 875 876 |
# File 'lib/origen/registers/bit_collection.rb', line 873 def clear_start each(&:clear_start) self end |
#clear_w1c ⇒ Object
Clear any w1c set bits back to 0
867 868 869 870 |
# File 'lib/origen/registers/bit_collection.rb', line 867 def clear_w1c each(&:clear_w1c) self end |
#clr_only(value) ⇒ Object
Modify clr_only for bits in collection
848 849 850 851 |
# File 'lib/origen/registers/bit_collection.rb', line 848 def clr_only(value) shift_out_with_index { |bit, i| bit.clr_only = (value[i] == 0b1) } self end |
#contains_bits? ⇒ Boolean
318 319 320 |
# File 'lib/origen/registers/bit_collection.rb', line 318 def contains_bits? true end |
#copy_all(reg) ⇒ Object
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.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# 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].(source_bit.) if source_bit. 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 ⇒ Object Also known as: val, value
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
335 336 337 338 339 340 341 342 343 |
# 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 |
#data_b ⇒ Object
Returns the inverse of the data value held by the collection
348 349 350 351 |
# 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 ⇒ Object Also known as: reverse_data
Returns the reverse of the data value held by the collection
354 355 356 357 358 359 360 361 362 |
# 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 |
#delete ⇒ Object
Delete the contained bits from the parent Register
709 710 711 712 |
# File 'lib/origen/registers/bit_collection.rb', line 709 def delete @reg.delete_bits(self) self end |
#description(bitname = nil, options = {}) ⇒ Object
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)
274 275 276 277 278 279 280 281 |
# File 'lib/origen/registers/bit_collection.rb', line 274 def description(bitname = nil, = {}) bitname, = nil, bitname if bitname.is_a?(Hash) if name == :unknown [] else @reg.description(name, ) end end |
#enable_mask(operation) ⇒ Object
Returns a value representing the bit collection / register where a bit value of 1 means the bit is enabled for the given operation.
426 427 428 429 430 431 432 433 434 435 436 437 438 |
# File 'lib/origen/registers/bit_collection.rb', line 426 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. str += '1' else str += '0' end end str.to_i(2) end |
#enabled? ⇒ Boolean
831 832 833 |
# File 'lib/origen/registers/bit_collection.rb', line 831 def enabled? all?(&:enabled?) end |
#feature ⇒ Object Also known as: features
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
# File 'lib/origen/registers/bit_collection.rb', line 799 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 |
#full_name(bitname = nil, options = {}) ⇒ Object
283 284 285 286 287 288 |
# File 'lib/origen/registers/bit_collection.rb', line 283 def full_name(bitname = nil, = {}) bitname, = nil, bitname if bitname.is_a?(Hash) unless name == :unknown @reg.full_name(name, ) end end |
#has_feature_constraint?(name = nil) ⇒ Boolean Also known as: enabled_by_feature?
Return true if there is any feature associated with these bits
822 823 824 825 826 827 828 |
# File 'lib/origen/registers/bit_collection.rb', line 822 def has_feature_constraint?(name = nil) if !name any?(&:has_feature_constraint?) else any? { |bit| bit.enabled_by_feature?(name) } end end |
#has_known_value? ⇒ Boolean
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.
754 755 756 |
# File 'lib/origen/registers/bit_collection.rb', line 754 def has_known_value? all?(&:has_known_value?) end |
#has_overlay?(name = nil) ⇒ Boolean
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
547 548 549 |
# File 'lib/origen/registers/bit_collection.rb', line 547 def (name = nil) any? { |bit| bit.(name) } end |
#inspect ⇒ Object
322 323 324 |
# File 'lib/origen/registers/bit_collection.rb', line 322 def inspect "<#{self.class}:#{object_id}>" end |
#is_readable? ⇒ Boolean Also known as: readable?
Returns true if any bits in the collection are readable
842 843 844 |
# File 'lib/origen/registers/bit_collection.rb', line 842 def is_readable? any?(&:readable?) end |
#is_to_be_read? ⇒ Boolean
Returns true if any bits have the read flag set - see Bit#is_to_be_read? for more details.
508 509 510 |
# File 'lib/origen/registers/bit_collection.rb', line 508 def is_to_be_read? any?(&:is_to_be_read?) end |
#is_to_be_stored? ⇒ Boolean
Returns true if any bits have the store flag set - see Bit#is_to_be_stored? for more details.
514 515 516 |
# File 'lib/origen/registers/bit_collection.rb', line 514 def is_to_be_stored? any?(&:is_to_be_stored?) end |
#is_writable? ⇒ Boolean Also known as: writable?
Returns true if any bits in the collection are writable
836 837 838 |
# File 'lib/origen/registers/bit_collection.rb', line 836 def is_writable? any?(&:writable?) end |
#nvm_dep ⇒ Object
Return nvm_dep value held by collection
860 861 862 863 864 |
# File 'lib/origen/registers/bit_collection.rb', line 860 def nvm_dep nvm_dep = 0 shift_out_with_index { |bit, i| nvm_dep |= bit.nvm_dep << i } nvm_dep end |
#overlay(value) ⇒ Object
Attaches the supplied overlay string to all bits
Example
reg(:data).overlay("data_val")
443 444 445 446 |
# File 'lib/origen/registers/bit_collection.rb', line 443 def (value) each { |bit| bit.(value) } self end |
#overlay_str ⇒ Object
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. # => "data"
557 558 559 560 561 562 563 |
# File 'lib/origen/registers/bit_collection.rb', line 557 def result = '' each do |bit| result = bit. if bit. end result.to_s end |
#owner ⇒ Object
723 724 725 |
# File 'lib/origen/registers/bit_collection.rb', line 723 def owner first.owner end |
#parent ⇒ Object
108 109 110 |
# File 'lib/origen/registers/bit_collection.rb', line 108 def parent @reg end |
#path_var ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# 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 ⇒ Object
Returns the LSB position of the collection
327 328 329 |
# File 'lib/origen/registers/bit_collection.rb', line 327 def position first.position end |
#preserve_flags ⇒ Object
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
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/origen/registers/bit_collection.rb', line 195 def preserve_flags orig = [] each do |bit| orig << [bit., bit.is_to_be_read?, bit.is_to_be_stored?] end yield each do |bit| bit.clear_flags flags = orig.shift bit.(flags[0]) bit.read if flags[1] bit.store if flags[2] end self end |
#read(value = nil, options = {}) ⇒ Object Also known as: assert
Will tag all bits for read and if a data value is supplied it will update the expected data for when the read is performed.
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/origen/registers/bit_collection.rb', line 404 def read(value = nil, = {}) # :nodoc: # First properly assign the args if value is absent... if value.is_a?(Hash) = value value = nil end if value value = Reg.clean_value(value) write(value, force: true) end if [:mask] shift_out_with_index { |bit, i| bit.read if [:mask][i] == 1 } shift_out_with_index { |bit, i| bit.clear_read_flag if [:mask][i] == 0 } else each(&:read) end self end |
#read!(value = nil, options = {}) ⇒ Object Also known as: assert!
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
585 586 587 588 589 590 591 592 593 |
# File 'lib/origen/registers/bit_collection.rb', line 585 def read!(value = nil, = {}) value, = nil, value if value.is_a?(Hash) read(value, ) unless block_given? if block_given? yield size == @reg.size ? @reg : self end @reg.request(:read_register, ) self end |
#readable(value) ⇒ Object
Modify readable for bits in collection
794 795 796 797 |
# File 'lib/origen/registers/bit_collection.rb', line 794 def readable(value) shift_out_with_index { |bit, i| bit.readable = (value[i] == 0b1); bit.set_access_from_rw } self end |
#reset ⇒ Object
Resets all bits, this clears all flags and assigns the data value back to the reset state
450 451 452 453 |
# File 'lib/origen/registers/bit_collection.rb', line 450 def reset each(&:reset) self end |
#reset_data(value = nil) ⇒ Object Also known as: reset_val, reset_value, reset_data=, reset_val=, reset_value=
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
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
# File 'lib/origen/registers/bit_collection.rb', line 766 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 |
#respond_to?(*args) ⇒ Boolean
Recognize that BitCollection responds to some Bit methods via method_missing
746 747 748 749 |
# File 'lib/origen/registers/bit_collection.rb', line 746 def respond_to?(*args) # :nodoc: sym = args.first first.respond_to?(sym) || super(sym) end |
#reverse_shift_out(&block) ⇒ Object
Yields each bit in the register, MSB first.
497 498 499 |
# File 'lib/origen/registers/bit_collection.rb', line 497 def reverse_shift_out(&block) reverse_each(&block) end |
#reverse_shift_out_with_index(&block) ⇒ Object
Yields each bit in the register and its index, MSB first.
502 503 504 |
# File 'lib/origen/registers/bit_collection.rb', line 502 def reverse_shift_out_with_index(&block) reverse_each.with_index(&block) end |
#set_only(value) ⇒ Object
Modify set_only for bits in collection
854 855 856 857 |
# File 'lib/origen/registers/bit_collection.rb', line 854 def set_only(value) shift_out_with_index { |bit, i| bit.set_only = (value[i] == 0b1) } self end |
#setting(value) ⇒ Object
Returns the value you would need to write to the register to put the given value in these bits
532 533 534 535 536 537 538 |
# File 'lib/origen/registers/bit_collection.rb', line 532 def setting(value) result = 0 shift_out_with_index do |bit, i| result |= bit.setting(value[i]) end result end |
#shift_left(data = 0) ⇒ Object
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).
958 959 960 961 962 963 964 965 966 |
# File 'lib/origen/registers/bit_collection.rb', line 958 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) ⇒ Object
Yields each bit in the register, LSB first.
487 488 489 |
# File 'lib/origen/registers/bit_collection.rb', line 487 def shift_out(&block) each(&block) end |
#shift_out_left ⇒ Object
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
463 464 465 466 |
# File 'lib/origen/registers/bit_collection.rb', line 463 def shift_out_left # This is functionally equivalent to reverse_shift_out reverse_each { |bit| yield bit } end |
#shift_out_left_with_index ⇒ Object
Same as Reg#shift_out_left but includes the index counter
469 470 471 472 |
# File 'lib/origen/registers/bit_collection.rb', line 469 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 ⇒ Object
Same as Reg#shift_out_left but starts from the LSB
475 476 477 478 |
# File 'lib/origen/registers/bit_collection.rb', line 475 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 ⇒ Object
Same as Reg#shift_out_right but includes the index counter
481 482 483 484 |
# File 'lib/origen/registers/bit_collection.rb', line 481 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) ⇒ Object
Yields each bit in the register and its index, LSB first.
492 493 494 |
# File 'lib/origen/registers/bit_collection.rb', line 492 def shift_out_with_index(&block) each_with_index(&block) end |
#shift_right(data = 0) ⇒ Object
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).
981 982 983 984 985 986 987 988 989 |
# File 'lib/origen/registers/bit_collection.rb', line 981 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 = {}) ⇒ Object
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
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 |
# File 'lib/origen/registers/bit_collection.rb', line 904 def status_str(operation, = {}) = { mark_overlays: true }.merge() 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. && [: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. && [: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) ⇒ Object Also known as: sticky_overlays
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
611 612 613 614 |
# File 'lib/origen/registers/bit_collection.rb', line 611 def (set = true) each { |bit| bit. = set } self end |
#sticky_store(set = true) ⇒ Object
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
625 626 627 628 |
# File 'lib/origen/registers/bit_collection.rb', line 625 def sticky_store(set = true) each { |bit| bit.sticky_store = set } self end |
#store(options = {}) ⇒ Object
Marks all bits to be stored
631 632 633 634 |
# File 'lib/origen/registers/bit_collection.rb', line 631 def store( = {}) each(&:store) self end |
#store!(options = {}) ⇒ Object
Marks all bits to be stored and then calls read!
637 638 639 640 641 |
# File 'lib/origen/registers/bit_collection.rb', line 637 def store!( = {}) store() read!() self end |
#store_overlay_bits(options = {}) ⇒ Object
Sets the store flag on all bits that already have the overlay flag set
653 654 655 656 657 658 659 660 |
# File 'lib/origen/registers/bit_collection.rb', line 653 def ( = {}) # Pass in an array of any overlays that are to be excluded from store = { exclude: [] }.merge() each do |bit| bit.store if bit. && ![:exclude].include?(bit.) end self end |
#store_overlay_bits!(options = {}) ⇒ Object
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
645 646 647 648 649 650 |
# File 'lib/origen/registers/bit_collection.rb', line 645 def ( = {}) () @reg.request(:read_register, ) # Bypass the normal read method since we don't want to # tag the other bits for read self end |
#sync(size = nil, options = {}) ⇒ Object Also known as: sync!
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.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/origen/registers/bit_collection.rb', line 152 def sync(size = nil, = {}) size, = 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 |
#terminal? ⇒ Boolean
63 64 65 |
# File 'lib/origen/registers/bit_collection.rb', line 63 def terminal? true end |
#unique_overlays {|current_overlay, length, data| ... } ⇒ Object
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
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 |
# File 'lib/origen/registers/bit_collection.rb', line 669 def = false length = 0 data = 0 shift_out_right do |bit| # Init the current overlay when the first one is encountered = bit. if bit. && ! if bit. if bit. != yield , length, data if length = 0 data = 0 end data = data | (bit.data << length) length += 1 else yield , length, data if length = 0 data = 0 = false end end yield , length, data if end |
#unknown=(val) ⇒ Object
Sets the unknown attribute on all contained bits
398 399 400 |
# File 'lib/origen/registers/bit_collection.rb', line 398 def unknown=(val) each { |bit| bit.unknown = val } end |
#update_required? ⇒ Boolean
Returns true if any bits have the update_required flag set - see Bit#update_required? for more details.
520 521 522 |
# File 'lib/origen/registers/bit_collection.rb', line 520 def update_required? any?(&:update_required?) end |
#whole_reg? ⇒ Boolean
Returns true if the collection contains all bits in the register
371 372 373 |
# File 'lib/origen/registers/bit_collection.rb', line 371 def whole_reg? size == parent.size end |
#with_bit_order ⇒ Object
Returns the bit numbering order to use when interpreting indeces
39 40 41 |
# File 'lib/origen/registers/bit_collection.rb', line 39 def with_bit_order @with_bit_order end |
#with_lsb0 ⇒ Object
Allow bit number interpreting to be explicitly set to lsb0
50 51 52 53 54 55 56 57 58 59 60 61 |
# 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 ⇒ Object
Allow bit number interpreting to be explicitly set to msb0
44 45 46 47 |
# File 'lib/origen/registers/bit_collection.rb', line 44 def with_msb0 @with_bit_order = :msb0 self end |
#writable(value) ⇒ Object
Modify writable for bits in collection
788 789 790 791 |
# File 'lib/origen/registers/bit_collection.rb', line 788 def writable(value) shift_out_with_index { |bit, i| bit.writable = (value[i] == 0b1); bit.set_access_from_rw } self end |
#write(value, options = {}) ⇒ Object Also known as: data=, value=, val=
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.
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/origen/registers/bit_collection.rb', line 377 def write(value, = {}) # 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) (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], ) end end self end |
#write!(value = nil, options = {}) ⇒ Object
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.
569 570 571 572 573 574 575 576 577 |
# File 'lib/origen/registers/bit_collection.rb', line 569 def write!(value = nil, = {}) value, = nil, value if value.is_a?(Hash) write(value, ) if value if block_given? yield size == @reg.size ? @reg : self end @reg.request(:write_register, ) self end |