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
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 |
# File 'lib/origen/registers/bit_collection.rb', line 724 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.
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/origen/registers/bit_collection.rb', line 300 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 |
# 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
129 130 131 |
# File 'lib/origen/registers/bit_collection.rb', line 129 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
248 249 250 251 252 253 254 255 |
# File 'lib/origen/registers/bit_collection.rb', line 248 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
259 260 261 262 263 264 265 |
# File 'lib/origen/registers/bit_collection.rb', line 259 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:
710 711 712 713 714 715 716 717 |
# File 'lib/origen/registers/bit_collection.rb', line 710 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"
697 698 699 700 701 702 |
# File 'lib/origen/registers/bit_collection.rb', line 697 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
288 289 290 291 292 293 294 295 |
# File 'lib/origen/registers/bit_collection.rb', line 288 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
521 522 523 524 |
# File 'lib/origen/registers/bit_collection.rb', line 521 def clear_flags each(&:clear_flags) self end |
#clear_start ⇒ Object
Clear any start set bits back to 0
867 868 869 870 |
# File 'lib/origen/registers/bit_collection.rb', line 867 def clear_start each(&:clear_start) self end |
#clear_w1c ⇒ Object
Clear any w1c set bits back to 0
861 862 863 864 |
# File 'lib/origen/registers/bit_collection.rb', line 861 def clear_w1c each(&:clear_w1c) self end |
#clr_only(value) ⇒ Object
Modify clr_only for bits in collection
842 843 844 845 |
# File 'lib/origen/registers/bit_collection.rb', line 842 def clr_only(value) shift_out_with_index { |bit, i| bit.clr_only = (value[i] == 0b1) } self end |
#contains_bits? ⇒ Boolean
316 317 318 |
# File 'lib/origen/registers/bit_collection.rb', line 316 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.
214 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 |
# File 'lib/origen/registers/bit_collection.rb', line 214 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
333 334 335 336 337 338 339 340 |
# File 'lib/origen/registers/bit_collection.rb', line 333 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
345 346 347 348 |
# File 'lib/origen/registers/bit_collection.rb', line 345 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
351 352 353 354 355 356 357 358 |
# File 'lib/origen/registers/bit_collection.rb', line 351 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
705 706 707 708 |
# File 'lib/origen/registers/bit_collection.rb', line 705 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)
272 273 274 275 276 277 278 279 |
# File 'lib/origen/registers/bit_collection.rb', line 272 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.
422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/origen/registers/bit_collection.rb', line 422 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
825 826 827 |
# File 'lib/origen/registers/bit_collection.rb', line 825 def enabled? all?(&:enabled?) end |
#feature ⇒ Object Also known as: features
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
# File 'lib/origen/registers/bit_collection.rb', line 794 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 return feature[0] else return feature.uniq end else if Origen.config.strict_errors fail 'No feature found' end return nil end end |
#full_name(bitname = nil, options = {}) ⇒ Object
281 282 283 284 285 286 |
# File 'lib/origen/registers/bit_collection.rb', line 281 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
816 817 818 819 820 821 822 |
# File 'lib/origen/registers/bit_collection.rb', line 816 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.
750 751 752 |
# File 'lib/origen/registers/bit_collection.rb', line 750 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
543 544 545 |
# File 'lib/origen/registers/bit_collection.rb', line 543 def (name = nil) any? { |bit| bit.(name) } end |
#inspect ⇒ Object
320 321 322 |
# File 'lib/origen/registers/bit_collection.rb', line 320 def inspect "<#{self.class}:#{object_id}>" end |
#is_readable? ⇒ Boolean Also known as: readable?
Returns true if any bits in the collection are readable
836 837 838 |
# File 'lib/origen/registers/bit_collection.rb', line 836 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.
504 505 506 |
# File 'lib/origen/registers/bit_collection.rb', line 504 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.
510 511 512 |
# File 'lib/origen/registers/bit_collection.rb', line 510 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
830 831 832 |
# File 'lib/origen/registers/bit_collection.rb', line 830 def is_writable? any?(&:writable?) end |
#nvm_dep ⇒ Object
Return nvm_dep value held by collection
854 855 856 857 858 |
# File 'lib/origen/registers/bit_collection.rb', line 854 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”)
439 440 441 442 |
# File 'lib/origen/registers/bit_collection.rb', line 439 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"
553 554 555 556 557 558 559 |
# File 'lib/origen/registers/bit_collection.rb', line 553 def result = '' each do |bit| result = bit. if bit. end result.to_s end |
#owner ⇒ Object
719 720 721 |
# File 'lib/origen/registers/bit_collection.rb', line 719 def owner first.owner end |
#parent ⇒ Object
107 108 109 |
# File 'lib/origen/registers/bit_collection.rb', line 107 def parent @reg end |
#path_var ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/origen/registers/bit_collection.rb', line 111 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
325 326 327 |
# File 'lib/origen/registers/bit_collection.rb', line 325 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
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/origen/registers/bit_collection.rb', line 194 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.
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/origen/registers/bit_collection.rb', line 400 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
581 582 583 584 585 586 587 588 589 |
# File 'lib/origen/registers/bit_collection.rb', line 581 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
789 790 791 792 |
# File 'lib/origen/registers/bit_collection.rb', line 789 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
446 447 448 449 |
# File 'lib/origen/registers/bit_collection.rb', line 446 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
762 763 764 765 766 767 768 769 770 771 772 773 774 775 |
# File 'lib/origen/registers/bit_collection.rb', line 762 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
742 743 744 745 |
# File 'lib/origen/registers/bit_collection.rb', line 742 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.
493 494 495 |
# File 'lib/origen/registers/bit_collection.rb', line 493 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.
498 499 500 |
# File 'lib/origen/registers/bit_collection.rb', line 498 def reverse_shift_out_with_index(&block) reverse_each.with_index(&block) end |
#set_only(value) ⇒ Object
Modify set_only for bits in collection
848 849 850 851 |
# File 'lib/origen/registers/bit_collection.rb', line 848 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
528 529 530 531 532 533 534 |
# File 'lib/origen/registers/bit_collection.rb', line 528 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).
952 953 954 955 956 957 958 959 960 |
# File 'lib/origen/registers/bit_collection.rb', line 952 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.
483 484 485 |
# File 'lib/origen/registers/bit_collection.rb', line 483 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
459 460 461 462 |
# File 'lib/origen/registers/bit_collection.rb', line 459 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
465 466 467 468 |
# File 'lib/origen/registers/bit_collection.rb', line 465 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
471 472 473 474 |
# File 'lib/origen/registers/bit_collection.rb', line 471 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
477 478 479 480 |
# File 'lib/origen/registers/bit_collection.rb', line 477 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.
488 489 490 |
# File 'lib/origen/registers/bit_collection.rb', line 488 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).
975 976 977 978 979 980 981 982 983 |
# File 'lib/origen/registers/bit_collection.rb', line 975 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
898 899 900 901 902 903 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 |
# File 'lib/origen/registers/bit_collection.rb', line 898 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
607 608 609 610 |
# File 'lib/origen/registers/bit_collection.rb', line 607 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
621 622 623 624 |
# File 'lib/origen/registers/bit_collection.rb', line 621 def sticky_store(set = true) each { |bit| bit.sticky_store = set } self end |
#store(options = {}) ⇒ Object
Marks all bits to be stored
627 628 629 630 |
# File 'lib/origen/registers/bit_collection.rb', line 627 def store( = {}) each(&:store) self end |
#store!(options = {}) ⇒ Object
Marks all bits to be stored and then calls read!
633 634 635 636 637 |
# File 'lib/origen/registers/bit_collection.rb', line 633 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
649 650 651 652 653 654 655 656 |
# File 'lib/origen/registers/bit_collection.rb', line 649 def ( = {}) = { exclude: [], # Pass in an array of any overlays that are to be excluded from store }.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
641 642 643 644 645 646 |
# File 'lib/origen/registers/bit_collection.rb', line 641 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.
151 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 |
# File 'lib/origen/registers/bit_collection.rb', line 151 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
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
# File 'lib/origen/registers/bit_collection.rb', line 665 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
394 395 396 |
# File 'lib/origen/registers/bit_collection.rb', line 394 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.
516 517 518 |
# File 'lib/origen/registers/bit_collection.rb', line 516 def update_required? any?(&:update_required?) end |
#whole_reg? ⇒ Boolean
Returns true if the collection contains all bits in the register
367 368 369 |
# File 'lib/origen/registers/bit_collection.rb', line 367 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
783 784 785 786 |
# File 'lib/origen/registers/bit_collection.rb', line 783 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.
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/origen/registers/bit_collection.rb', line 373 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.
565 566 567 568 569 570 571 572 573 |
# File 'lib/origen/registers/bit_collection.rb', line 565 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 |