Class: Origen::Registers::BitCollection
- Includes:
- 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.
Constant Summary collapse
- DONT_CARE_CHAR =
'X'
- OVERLAY_CHAR =
'V'
- STORE_CHAR =
'S'
Instance Attribute Summary collapse
-
#name ⇒ Object
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)
- #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_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.
-
#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 = []) ⇒ 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.
-
#read(value = nil, options = {}) ⇒ Object
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
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?(sym) ⇒ Boolean
Recognize that BitCollection responds to some Bit methods via method_missing.
-
#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_out_left ⇒ Object
Shifts out a stream of bit objects corresponding to the size of the BitCollection.
-
#shift_out_right ⇒ Object
Same as Reg#shift_out_left but starts from the MSB.
-
#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 ⇒ Object
Marks all bits to be stored.
-
#store! ⇒ 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.
-
#unique_overlays {|current_overlay, length, data| ... } ⇒ Object
Will yield all unique overlay strings attached to the bits within the collection.
-
#update_required? ⇒ Boolean
Returns true if any bits have the update_required flag set - see Bit#update_required? for more details.
-
#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
This method will update the data value of the bits and then call $top.write_register passing the owngin register as the first argument.
This method is expected to handle writing the current state of the register to silicon.
Methods included from SubBlocks::Path
Methods inherited from Array
#dups, #dups?, #dups_with_index, #ids
Constructor Details
#initialize(reg, name, data = []) ⇒ BitCollection
:nodoc:
20 21 22 23 24 25 26 27 |
# File 'lib/origen/registers/bit_collection.rb', line 20 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 [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
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
# File 'lib/origen/registers/bit_collection.rb', line 523 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
Returns the value of attribute name.
18 19 20 |
# File 'lib/origen/registers/bit_collection.rb', line 18 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.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/origen/registers/bit_collection.rb', line 169 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
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/origen/registers/bit_collection.rb', line 33 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 b end end |
#abs_path ⇒ Object
72 73 74 |
# File 'lib/origen/registers/bit_collection.rb', line 72 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
118 119 120 121 122 123 124 125 |
# File 'lib/origen/registers/bit_collection.rb', line 118 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
129 130 131 132 133 134 135 |
# File 'lib/origen/registers/bit_collection.rb', line 129 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:
509 510 511 512 513 514 515 516 |
# File 'lib/origen/registers/bit_collection.rb', line 509 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"
496 497 498 499 500 501 |
# File 'lib/origen/registers/bit_collection.rb', line 496 def (value) each do |bit| bit.(bit. + value) if bit. end self end |
#bind(live_parameter) ⇒ Object
29 30 31 |
# File 'lib/origen/registers/bit_collection.rb', line 29 def bind(live_parameter) parent.bind(name, live_parameter) end |
#bit_value_descriptions(_bitname = nil) ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/origen/registers/bit_collection.rb', line 158 def bit_value_descriptions(_bitname = nil) 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
326 327 328 329 |
# File 'lib/origen/registers/bit_collection.rb', line 326 def clear_flags each(&:clear_flags) self end |
#clear_start ⇒ Object
Clear any start set bits back to 0
665 666 667 668 |
# File 'lib/origen/registers/bit_collection.rb', line 665 def clear_start each(&:clear_start) self end |
#clear_w1c ⇒ Object
Clear any w1c set bits back to 0
659 660 661 662 |
# File 'lib/origen/registers/bit_collection.rb', line 659 def clear_w1c each(&:clear_w1c) self end |
#clr_only(value) ⇒ Object
Modify clr_only for bits in collection
640 641 642 643 |
# File 'lib/origen/registers/bit_collection.rb', line 640 def clr_only(value) each_with_index { |bit, i| bit.clr_only = (value[i] == 0b1) } self end |
#contains_bits? ⇒ Boolean
185 186 187 |
# File 'lib/origen/registers/bit_collection.rb', line 185 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.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/origen/registers/bit_collection.rb', line 86 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 size.times do |i| source_bit = reg.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 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
202 203 204 205 206 |
# File 'lib/origen/registers/bit_collection.rb', line 202 def data data = 0 each_with_index { |bit, i| data |= bit.data << i } data end |
#data_b ⇒ Object
Returns the inverse of the data value held by the collection
211 212 213 214 |
# File 'lib/origen/registers/bit_collection.rb', line 211 def data_b # (& operation takes care of Bignum formatting issues) ~data & ((1 << size) - 1) end |
#delete ⇒ Object
Delete the contained bits from the parent Register
504 505 506 507 |
# File 'lib/origen/registers/bit_collection.rb', line 504 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)
142 143 144 145 146 147 148 149 |
# File 'lib/origen/registers/bit_collection.rb', line 142 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.
261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/origen/registers/bit_collection.rb', line 261 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
623 624 625 |
# File 'lib/origen/registers/bit_collection.rb', line 623 def enabled? all?(&:enabled?) end |
#feature ⇒ Object Also known as: features
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/origen/registers/bit_collection.rb', line 592 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
151 152 153 154 155 156 |
# File 'lib/origen/registers/bit_collection.rb', line 151 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
614 615 616 617 618 619 620 |
# File 'lib/origen/registers/bit_collection.rb', line 614 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.
548 549 550 |
# File 'lib/origen/registers/bit_collection.rb', line 548 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
348 349 350 |
# File 'lib/origen/registers/bit_collection.rb', line 348 def (name = nil) any? { |bit| bit.(name) } end |
#inspect ⇒ Object
189 190 191 |
# File 'lib/origen/registers/bit_collection.rb', line 189 def inspect "<#{self.class}:#{object_id}>" end |
#is_readable? ⇒ Boolean Also known as: readable?
Returns true if any bits in the collection are readable
634 635 636 |
# File 'lib/origen/registers/bit_collection.rb', line 634 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.
309 310 311 |
# File 'lib/origen/registers/bit_collection.rb', line 309 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.
315 316 317 |
# File 'lib/origen/registers/bit_collection.rb', line 315 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
628 629 630 |
# File 'lib/origen/registers/bit_collection.rb', line 628 def is_writable? any?(&:writable?) end |
#nvm_dep ⇒ Object
Return nvm_dep value held by collection
652 653 654 655 656 |
# File 'lib/origen/registers/bit_collection.rb', line 652 def nvm_dep nvm_dep = 0 each_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”)
278 279 280 281 |
# File 'lib/origen/registers/bit_collection.rb', line 278 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"
358 359 360 361 362 363 364 |
# File 'lib/origen/registers/bit_collection.rb', line 358 def result = '' each do |bit| result = bit. if bit. end result.to_s end |
#owner ⇒ Object
518 519 520 |
# File 'lib/origen/registers/bit_collection.rb', line 518 def owner first.owner end |
#parent ⇒ Object
50 51 52 |
# File 'lib/origen/registers/bit_collection.rb', line 50 def parent @reg end |
#path_var ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/origen/registers/bit_collection.rb', line 54 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
194 195 196 |
# File 'lib/origen/registers/bit_collection.rb', line 194 def position first.position end |
#read(value = nil, options = {}) ⇒ Object
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.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/origen/registers/bit_collection.rb', line 240 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) end if [:mask] each_with_index { |bit, i| bit.read if [:mask][i] == 1 } each_with_index { |bit, i| bit.clear_read_flag if [:mask][i] == 0 } else each(&:read) end self end |
#read!(value = nil, options = {}) ⇒ Object
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
383 384 385 386 387 388 389 |
# File 'lib/origen/registers/bit_collection.rb', line 383 def read!(value = nil, = {}) value, = nil, value if value.is_a?(Hash) read(value, ) # launch a read reg @reg.request(:read_register, ) self end |
#readable(value) ⇒ Object
Modify readable for bits in collection
587 588 589 590 |
# File 'lib/origen/registers/bit_collection.rb', line 587 def readable(value) each_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
285 286 287 288 |
# File 'lib/origen/registers/bit_collection.rb', line 285 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
560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
# File 'lib/origen/registers/bit_collection.rb', line 560 def reset_data(value = nil) # This method was originally setup to set the reset value by passing an argument if value each_with_index { |bit, i| bit.reset_val = value[i] } self else data = 0 each_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?(sym) ⇒ Boolean
Recognize that BitCollection responds to some Bit methods via method_missing
541 542 543 |
# File 'lib/origen/registers/bit_collection.rb', line 541 def respond_to?(sym) # :nodoc: first.respond_to?(sym) || super(sym) end |
#set_only(value) ⇒ Object
Modify set_only for bits in collection
646 647 648 649 |
# File 'lib/origen/registers/bit_collection.rb', line 646 def set_only(value) each_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
333 334 335 336 337 338 339 |
# File 'lib/origen/registers/bit_collection.rb', line 333 def setting(value) result = 0 each_with_index do |bit, i| result |= bit.setting(value[i]) end result 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
298 299 300 |
# File 'lib/origen/registers/bit_collection.rb', line 298 def shift_out_left reverse_each { |bit| yield bit } end |
#shift_out_right ⇒ Object
Same as Reg#shift_out_left but starts from the MSB
303 304 305 |
# File 'lib/origen/registers/bit_collection.rb', line 303 def shift_out_right each { |bit| yield bit } 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
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
# File 'lib/origen/registers/bit_collection.rb', line 696 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 str += bit.data.to_s end else str += DONT_CARE_CHAR end end elsif operation == :write shift_out_left do |bit| if bit. && [:mark_overlays] str += OVERLAY_CHAR else str += bit.data.to_s end end else fail "Unknown operation (#{operation}), must be :read or :write" end make_hex_like(str, size / 4) 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
406 407 408 409 |
# File 'lib/origen/registers/bit_collection.rb', line 406 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
420 421 422 423 |
# File 'lib/origen/registers/bit_collection.rb', line 420 def sticky_store(set = true) each { |bit| bit.sticky_store = set } self end |
#store ⇒ Object
Marks all bits to be stored
426 427 428 429 |
# File 'lib/origen/registers/bit_collection.rb', line 426 def store each(&:store) self end |
#store! ⇒ Object
Marks all bits to be stored and then calls read!
432 433 434 435 436 |
# File 'lib/origen/registers/bit_collection.rb', line 432 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
448 449 450 451 452 453 454 455 |
# File 'lib/origen/registers/bit_collection.rb', line 448 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
440 441 442 443 444 445 |
# File 'lib/origen/registers/bit_collection.rb', line 440 def ( = {}) () @reg.request(:read_register, ) # Bypass the normal read method since we don't want to # tag the other bits for read self 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
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/origen/registers/bit_collection.rb', line 464 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 |
#update_required? ⇒ Boolean
Returns true if any bits have the update_required flag set - see Bit#update_required? for more details.
321 322 323 |
# File 'lib/origen/registers/bit_collection.rb', line 321 def update_required? any?(&:update_required?) end |
#writable(value) ⇒ Object
Modify writable for bits in collection
581 582 583 584 |
# File 'lib/origen/registers/bit_collection.rb', line 581 def writable(value) each_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.
223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/origen/registers/bit_collection.rb', line 223 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') each_with_index { |bit, i| bit.write(value[i], ) } 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 owngin register as the first argument.
This method is expected to handle writing the current state of the register to silicon.
370 371 372 373 374 375 |
# File 'lib/origen/registers/bit_collection.rb', line 370 def write!(value = nil, = {}) value, = nil, value if value.is_a?(Hash) write(value, ) if value @reg.request(:write_register, ) self end |