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 - 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
731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 |
# File 'lib/origen/registers/bit_collection.rb', line 731 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[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
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:
717 718 719 720 721 722 723 724 |
# File 'lib/origen/registers/bit_collection.rb', line 717 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).("data_val")
reg(:data).("_0")
reg(:data). # => "data_val_0"
704 705 706 707 708 709 |
# File 'lib/origen/registers/bit_collection.rb', line 704 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
528 529 530 531 |
# File 'lib/origen/registers/bit_collection.rb', line 528 def clear_flags each(&:clear_flags) self end |
#clear_start ⇒ Object
Clear any start set bits back to 0
876 877 878 879 |
# File 'lib/origen/registers/bit_collection.rb', line 876 def clear_start each(&:clear_start) self end |
#clear_w1c ⇒ Object
Clear any w1c set bits back to 0
870 871 872 873 |
# File 'lib/origen/registers/bit_collection.rb', line 870 def clear_w1c each(&:clear_w1c) self end |
#clr_only(value) ⇒ Object
Modify clr_only for bits in collection
851 852 853 854 |
# 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? ⇒ 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
712 713 714 715 |
# File 'lib/origen/registers/bit_collection.rb', line 712 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.
429 430 431 432 433 434 435 436 437 438 439 440 441 |
# 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. str += '1' else str += '0' end end str.to_i(2) end |
#enabled? ⇒ Boolean
834 835 836 |
# File 'lib/origen/registers/bit_collection.rb', line 834 def enabled? all?(&:enabled?) end |
#feature ⇒ Object Also known as: features
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
# 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 |
#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
825 826 827 828 829 830 831 |
# 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 |
#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.
757 758 759 |
# File 'lib/origen/registers/bit_collection.rb', line 757 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.("data")
myreg. # => true
myreg.("address") # => false
myreg.("data") # => true
550 551 552 |
# File 'lib/origen/registers/bit_collection.rb', line 550 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
845 846 847 |
# File 'lib/origen/registers/bit_collection.rb', line 845 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.
511 512 513 |
# File 'lib/origen/registers/bit_collection.rb', line 511 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.
517 518 519 |
# File 'lib/origen/registers/bit_collection.rb', line 517 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
839 840 841 |
# File 'lib/origen/registers/bit_collection.rb', line 839 def is_writable? any?(&:writable?) end |
#nvm_dep ⇒ Object
Return nvm_dep value held by collection
863 864 865 866 867 |
# 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) ⇒ Object
Attaches the supplied overlay string to all bits
Example
reg(:data).overlay(“data_val”)
446 447 448 449 |
# File 'lib/origen/registers/bit_collection.rb', line 446 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.("data")
myreg. # => "data"
560 561 562 563 564 565 566 |
# File 'lib/origen/registers/bit_collection.rb', line 560 def result = '' each do |bit| result = bit. if bit. end result.to_s end |
#owner ⇒ Object
726 727 728 |
# File 'lib/origen/registers/bit_collection.rb', line 726 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.
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/origen/registers/bit_collection.rb', line 407 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
588 589 590 591 592 593 594 595 596 |
# File 'lib/origen/registers/bit_collection.rb', line 588 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
797 798 799 800 |
# 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 |
#reset ⇒ Object
Resets all bits, this clears all flags and assigns the data value back to the reset state
453 454 455 456 |
# File 'lib/origen/registers/bit_collection.rb', line 453 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
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 |
# 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 |
#respond_to?(*args) ⇒ Boolean
Recognize that BitCollection responds to some Bit methods via method_missing
749 750 751 752 |
# File 'lib/origen/registers/bit_collection.rb', line 749 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.
500 501 502 |
# File 'lib/origen/registers/bit_collection.rb', line 500 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.
505 506 507 |
# 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) ⇒ Object
Modify set_only for bits in collection
857 858 859 860 |
# 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) ⇒ Object
Returns the value you would need to write to the register to put the given value in these bits
535 536 537 538 539 540 541 |
# 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) ⇒ 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).
961 962 963 964 965 966 967 968 969 |
# 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) ⇒ Object
Yields each bit in the register, LSB first.
490 491 492 |
# File 'lib/origen/registers/bit_collection.rb', line 490 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
466 467 468 469 |
# 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 ⇒ Object
Same as Reg#shift_out_left but includes the index counter
472 473 474 475 |
# 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 ⇒ Object
Same as Reg#shift_out_left but starts from the LSB
478 479 480 481 |
# 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 ⇒ Object
Same as Reg#shift_out_right but includes the index counter
484 485 486 487 |
# 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) ⇒ Object
Yields each bit in the register and its index, LSB first.
495 496 497 |
# File 'lib/origen/registers/bit_collection.rb', line 495 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).
984 985 986 987 988 989 990 991 992 |
# 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 = {}) ⇒ 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
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 944 945 946 |
# File 'lib/origen/registers/bit_collection.rb', line 907 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).("data_val")
reg(:data). # => true
reg(:data).clear_flags
reg(:data). # => true
reg(:data).(false)
reg(:data).clear_flags
reg(:data). # => false
614 615 616 617 |
# File 'lib/origen/registers/bit_collection.rb', line 614 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
628 629 630 631 |
# File 'lib/origen/registers/bit_collection.rb', line 628 def sticky_store(set = true) each { |bit| bit.sticky_store = set } self end |
#store(options = {}) ⇒ Object
Marks all bits to be stored
634 635 636 637 |
# File 'lib/origen/registers/bit_collection.rb', line 634 def store( = {}) each(&:store) self end |
#store!(options = {}) ⇒ Object
Marks all bits to be stored and then calls read!
640 641 642 643 644 |
# File 'lib/origen/registers/bit_collection.rb', line 640 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
656 657 658 659 660 661 662 663 |
# File 'lib/origen/registers/bit_collection.rb', line 656 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
648 649 650 651 652 653 |
# File 'lib/origen/registers/bit_collection.rb', line 648 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). do |str, length, data|
do_something(str, length, data)
end
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'lib/origen/registers/bit_collection.rb', line 672 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
401 402 403 |
# File 'lib/origen/registers/bit_collection.rb', line 401 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.
523 524 525 |
# File 'lib/origen/registers/bit_collection.rb', line 523 def update_required? any?(&:update_required?) end |
#whole_reg? ⇒ Boolean
Returns true if the collection contains all bits in the register
374 375 376 |
# File 'lib/origen/registers/bit_collection.rb', line 374 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
791 792 793 794 |
# 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 |
#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.
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/origen/registers/bit_collection.rb', line 380 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.
572 573 574 575 576 577 578 579 580 |
# File 'lib/origen/registers/bit_collection.rb', line 572 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 |