Class: Origen::Registers::Reg
- Includes:
- SubBlocks::Domains, SubBlocks::Path
- Defined in:
- lib/origen/registers/reg.rb
Overview
The register class can be used to represent not only h/ware resgisters, but really any entity which has an address and data component, such as a specific RAM location.
Any registers instantiated through Origen::Registers#add_reg are instances of this class.
All methods in BitCollection can also be called on a Reg object.
Constant Summary collapse
- REG_LEVEL_ATTRIBUTES =
These attributes can be defined on a register at definition time and will get applied to all of its contained bits unless a specific bit has its own definition of the same attribute
{ feature: {}, reset: { aliases: [:res] }, memory: {}, path: { aliases: [:hdl_path] }, abs_path: { aliases: [:absolute_path] }, access: {} }
Instance Attribute Summary collapse
-
#address(options = {}) ⇒ Object
(also: #addr)
Returns the register address added to its current base_address value (if any).
-
#base_address ⇒ Object
The base address of the register, this will be set dynamically by Origen based on the parent’s base address.
-
#define_file ⇒ Object
readonly
Returns a full path to the file in which the register was defined.
-
#feature ⇒ Object
Any feature associated with the register.
-
#grows_backwards ⇒ Object
:nodoc:.
-
#lookup ⇒ Object
:nodoc:.
-
#memory ⇒ Object
If the given register’s reset data is backed by memory, the memory address can be recorded in this attribute.
-
#meta ⇒ Object
(also: #meta_data, #metadata)
Returns any application-specific meta-data attatched to the given register.
-
#name ⇒ Object
The register name.
-
#owner ⇒ Object
(also: #parent)
readonly
Returns the object that own the register.
-
#size ⇒ Object
readonly
Returns an integer representing the number of bits in the register.
Class Method Summary collapse
-
.clean_value(value) ⇒ Object
Cleans an input value, in some cases it could be a register object, or an explicit value.
-
.dummy(size = 16) ⇒ Object
Returns a dummy register object that can be used on the fly, this can sometimes be useful to configure an intricate read operation.
Instance Method Summary collapse
-
#&(val) ⇒ Object
Returns the BITWISE AND of reg with another reg or a number, the state of both registers remains unchanged ==== Example reg(:data).write(0x5555) reg(:data2).write(0xFFFF) reg(:data) & 0xFF00 # => 0x5500 reg(:data) & reg(:data2) # => 0x5555.
-
#*(val) ⇒ Object
Returns the PRODUCT of reg with another reg or a number, the state of both registers remains unchanged.
-
#+(val) ⇒ Object
Returns the SUM of reg with another reg or a number, the state of both registers remains unchanged.
-
#-(val) ⇒ Object
Returns the SUBTRACTION of reg with another reg or a number, the state of both registers remains unchanged.
-
#/(val) ⇒ Object
Returns the DIVISION of reg with another reg or a number, the state of both registers remains unchanged.
-
#add_bit(id, position, options = {}) ⇒ Object
Add a bit to the register, should only be called internally.
- #add_bits_from_options(options = {}) ⇒ Object private
-
#add_bus(id, position, size, options = {}) ⇒ Object
Add a bus to the register, should only be called internally.
- #add_bus_scramble(id, array_of_hashes = []) ⇒ Object
- #bind(bitname, live_parameter) ⇒ Object
-
#bit(*args) ⇒ Object
(also: #bits, #[])
Returns the bit object(s) responding to the given name, wrapped in a BitCollection.
- #bit_value_descriptions(bitname, options = {}) ⇒ Object
- #contains_bits? ⇒ Boolean
-
#copy(reg) ⇒ Object
Copies data and overlays from one reg object to another, it does not copy read or store flags.
-
#copy_data_from(reg) ⇒ Object
Copies data from one reg object to another ==== Example reg(:data_copy).data # => 0 reg(:data).write(0x1234) reg(:data_copy).copy_data_from(reg(:data)) reg(:data_copy).data # => 0x1234.
-
#copy_overlays_from(reg, options = {}) ⇒ Object
Copy overlays from one reg object to another ==== Example reg(:data_copy).has_overlay? # => false reg(:data).overlay(“data_val”) reg(:data_copy).copy_overlays_from(reg(:data)) reg(:data_copy).has_overlay? # => true.
-
#default_reg_metadata ⇒ Object
Returns any application specific metadata that has been inherited by the given register.
-
#delete_bit(collection) ⇒ Object
(also: #delete_bits)
Delete the bits in the collection from the register.
-
#description(bitname = :_reg, options = {}) ⇒ Object
(also: #descriptions)
Returns the description of this register if any, if none then an empty array will be returned.
-
#description_lookup ⇒ Object
private
Returns a hash containing all register descriptions that have been parsed so far.
-
#empty_bits(_options = {}) ⇒ Object
Returns an array of unoccupied bit positions ==== Example reg :fstat, @base + 0x0000, :size => 8 do bit 7, :ccif bit 6, :rdcolerr bit 5, :accerr bit 4, :pviol bit 0, :mgstat0 end regs(:fstat).empty_bits => [1, 2, 3].
-
#empty_bits?(_options = {}) ⇒ Boolean
Returns true if any named_bits exist, false if used_bits is an empty array.
-
#enabled? ⇒ Boolean
Query the owner heirarchy to see if this register is enabled.
-
#enabled_by_feature?(name = nil) ⇒ Boolean
(also: #has_feature_constraint?)
Returns true if the register is constrained by the given/any feature.
-
#escape_special_char(str) ⇒ Object
Escapes brackets and parenthesis.
- #expand_range(range) ⇒ Object private
- #extract_feature_params(args) ⇒ Object
- #extract_meta_data(method, *args) ⇒ Object
- #freeze ⇒ Object
-
#full_name(bitname = :_reg, _options = {}) ⇒ Object
Returns the full name of the register when this has been specified in the register description like this:.
- #get_bits_with_constraint(number, params) ⇒ Object
- #get_lookup_feature_bits(bit_name, params, split_group_reg) ⇒ Object
-
#has_bit?(name) ⇒ Boolean
(also: #has_bits?, #has_bit, #has_bits)
Returns true if the register contains a bit(s) matching the given name ==== Example add_reg :control, 0x55, :status => => 1.
-
#has_bits_enabled_by_feature?(name = nil) ⇒ Boolean
Returns true if any of the bits within this register has feature associated with it.
- #has_parameter_bound_bits? ⇒ Boolean
-
#initialize(owner, address, size, name, options = {}) ⇒ Reg
constructor
Normally shouldn’t be called directly, instantiate through add_reg Upon initialization bits are stored as follows: An array of bit objects in position order, @bits corresponds to the bit as position r A Hash lookup table for quickly accessing bit objects by name.
-
#initialize_copy(orig) ⇒ Object
This method is called whenever reg.clone is called to make a copy of a given register.
- #inspect ⇒ Object
- #lookup_operation_handler(operation) ⇒ Object private
- #meta_data_method?(method) ⇒ Boolean private
-
#method_missing(method, *args, &block) ⇒ Object
All other Reg methods are delegated to BitCollection.
-
#named_bits(options = {}) ⇒ Object
Returns each named bit collection contained in the register,.
-
#offset ⇒ Object
Returns the relative address of the given register, equivalent to calling reg.address(:relative => true).
-
#owned_by?(name) ⇒ Boolean
Returns true if the register owner matches the given name.
- #parse_descriptions ⇒ Object private
-
#reader ⇒ Object
Returns the object that will be responsible for reading the given register.
-
#request(operation, options = {}) ⇒ Object
Proxies requests from bit collections to the register owner.
-
#respond_to?(sym) ⇒ Boolean
Recognize that Reg responds to all BitCollection methods methods based on application-specific meta data properties.
-
#reverse_named_bits(_options = {}) ⇒ Object
Returns each named bit collection contained in self.
- #update_bound_bits ⇒ Object
- #updating_bound_bits? ⇒ Boolean
-
#used_bits(_options = {}) ⇒ Object
Returns an array of occupied bit positions ==== Example reg :fstat, @base + 0x0000, :size => 8 do bit 7, :ccif bit 6, :rdcolerr bit 5, :accerr bit 4, :pviol bit 0, :mgstat0 end regs(:fstat).used_bits => [0, 4, 5, 6, 7].
-
#used_bits?(_options = {}) ⇒ Boolean
Returns true if any named_bits exist, false if used_bits is an empty array.
-
#writer ⇒ Object
Returns the object that will be responsible for writing the given register.
-
#|(val) ⇒ Object
Returns the BITWISE OR of reg with another reg or a number, the state of both registers remains unchanged.
Methods included from SubBlocks::Domains
#domain, #domain_specified?, #domains
Methods included from SubBlocks::Path
#abs_path, #abs_path=, #path, #path=, #path_var
Constructor Details
#initialize(owner, address, size, name, options = {}) ⇒ Reg
Normally shouldn’t be called directly, instantiate through add_reg Upon initialization bits are stored as follows: An array of bit objects in position order, @bits corresponds to the bit as position r A Hash lookup table for quickly accessing bit objects by name
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/origen/registers/reg.rb', line 60 def initialize(owner, address, size, name, = {}) # :nodoc: @owner = owner @address = address @size = size @bits = [] @lookup = {} @name = name @init_as_writable = .delete(:init_as_writable) @define_file = .delete(:define_file) REG_LEVEL_ATTRIBUTES.each do |attribute, | instance_variable_set("@#{attribute}", .delete(attribute)) end @description_from_api = {} description = .delete(:description) if description @description_from_api[:_reg] = description.split(/\r?\n/) end = .merge(.delete(:meta) || {}) # Initialize with unwritable bits that read back as zero, can override this # to make all writable by default by setting the :init_writable option to true @size.times do |n| @bits << Bit.new(self, n, writable: @init_as_writable, undefined: true) end () end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
All other Reg methods are delegated to BitCollection
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
# File 'lib/origen/registers/reg.rb', line 1107 def method_missing(method, *args, &block) # :nodoc: if method.to_sym == :to_ary || method.to_sym == :to_hash nil elsif (method) (method, *args) else if BitCollection.instance_methods.include?(method) BitCollection.new(self, name, @bits).send(method, *args, &block) elsif has_bits?(method) bits(method) else super end end end |
Instance Attribute Details
#address(options = {}) ⇒ Object Also known as: addr
Returns the register address added to its current base_address value (if any).
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 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 |
# File 'lib/origen/registers/reg.rb', line 702 def address( = {}) = { relative: false }.merge() address = @address domain_option = [:domains] || [:domain] @domain_option ||= domain_option unless frozen? # Blow the cache when the domain option changes @base_address_applied = nil unless @domain_option == domain_option unless @base_address_applied # Give highest priority to the original API which allowed the object # doing register read/write to define a base_address method if (writer && writer.methods.include?(:base_address) && writer.method(:base_address).arity != 0) || (reader && reader.methods.include?(:base_address) && reader.method(:base_address).arity != 0) # This currently assumes that the base address is always the same # for reading and writing if writer && writer.respond_to?(:base_address) && writer.method(:base_address).arity != 0 self.base_address = writer.base_address(self) elsif reader && reader.respond_to?(:base_address) && reader.method(:base_address).arity != 0 self.base_address = reader.base_address(self) end else o = owner.is_a?(Container) ? owner.owner : owner d = domain_option || domains if o && o.reg_base_address(domain: d) self.base_address = o.reg_base_address(domain: d) end end @base_address_applied = true end unless [:relative] address += base_address if base_address end if [:address_type] Origen.deprecate 'Specifying the address_type of a register address will be removed from Origen 3' case [:address_type] when :byte address = address * 2 when :word address = address when :longword address = address / 2 else fail 'Unknown address type requested!' end end address end |
#base_address ⇒ Object
The base address of the register, this will be set dynamically by Origen based on the parent’s base address
31 32 33 |
# File 'lib/origen/registers/reg.rb', line 31 def base_address @base_address end |
#define_file ⇒ Object (readonly)
Returns a full path to the file in which the register was defined
43 44 45 |
# File 'lib/origen/registers/reg.rb', line 43 def define_file @define_file end |
#feature ⇒ Object
Any feature associated with the register
38 39 40 |
# File 'lib/origen/registers/reg.rb', line 38 def feature @feature end |
#grows_backwards ⇒ Object
:nodoc:
40 41 42 |
# File 'lib/origen/registers/reg.rb', line 40 def grows_backwards @grows_backwards end |
#lookup ⇒ Object
:nodoc:
41 42 43 |
# File 'lib/origen/registers/reg.rb', line 41 def lookup @lookup end |
#memory ⇒ Object
If the given register’s reset data is backed by memory, the memory address can be recorded in this attribute
50 51 52 |
# File 'lib/origen/registers/reg.rb', line 50 def memory @memory end |
#meta ⇒ Object Also known as: meta_data, metadata
Returns any application-specific meta-data attatched to the given register
45 46 47 |
# File 'lib/origen/registers/reg.rb', line 45 def end |
#name ⇒ Object
The register name
36 37 38 |
# File 'lib/origen/registers/reg.rb', line 36 def name @name end |
#owner ⇒ Object (readonly) Also known as: parent
Returns the object that own the register.
Example
$soc.reg(:blah).owner # Returns the $soc object
27 28 29 |
# File 'lib/origen/registers/reg.rb', line 27 def owner @owner end |
#size ⇒ Object (readonly)
Returns an integer representing the number of bits in the register
34 35 36 |
# File 'lib/origen/registers/reg.rb', line 34 def size @size end |
Class Method Details
.clean_value(value) ⇒ Object
Cleans an input value, in some cases it could be a register object, or an explicit value. This will return an explicit value in either case.
1217 1218 1219 1220 |
# File 'lib/origen/registers/reg.rb', line 1217 def self.clean_value(value) # :nodoc: value = value.val if value.respond_to?('val') # Pull out the data value if a reg object has been passed in value end |
.dummy(size = 16) ⇒ Object
Returns a dummy register object that can be used on the fly, this can sometimes be useful to configure an intricate read operation.
Example
# Read bit 5 of RAM address 0xFFFF1280
dummy = Reg.dummy # Create a dummy reg to configure the read operation
dummy.address = 0xFFFF1280 # Set the address
dummy.bit(5).read!(1) # Read bit 5 expecting a 1
469 470 471 |
# File 'lib/origen/registers/reg.rb', line 469 def self.dummy(size = 16) Reg.new(self, 0, size, :dummy, init_as_writable: true) end |
Instance Method Details
#&(val) ⇒ Object
Returns the BITWISE AND of reg with another reg or a number, the state of both registers remains unchanged
Example
reg(:data).write(0x5555)
reg(:data2).write(0xFFFF)
reg(:data) & 0xFF00 # => 0x5500
reg(:data) & reg(:data2) # => 0x5555
1181 1182 1183 |
# File 'lib/origen/registers/reg.rb', line 1181 def &(val) data & Reg.clean_value(val) end |
#*(val) ⇒ Object
Returns the PRODUCT of reg with another reg or a number, the state of both registers remains unchanged
1211 1212 1213 |
# File 'lib/origen/registers/reg.rb', line 1211 def *(val) data * Reg.clean_value(val) end |
#+(val) ⇒ Object
Returns the SUM of reg with another reg or a number, the state of both registers remains unchanged
1193 1194 1195 |
# File 'lib/origen/registers/reg.rb', line 1193 def +(val) data + Reg.clean_value(val) end |
#-(val) ⇒ Object
Returns the SUBTRACTION of reg with another reg or a number, the state of both registers remains unchanged
1199 1200 1201 |
# File 'lib/origen/registers/reg.rb', line 1199 def -(val) data - Reg.clean_value(val) end |
#/(val) ⇒ Object
Returns the DIVISION of reg with another reg or a number, the state of both registers remains unchanged
1205 1206 1207 |
# File 'lib/origen/registers/reg.rb', line 1205 def /(val) data / Reg.clean_value(val) end |
#add_bit(id, position, options = {}) ⇒ Object
Add a bit to the register, should only be called internally
825 826 827 828 829 830 831 832 833 834 835 |
# File 'lib/origen/registers/reg.rb', line 825 def add_bit(id, position, = {}) # :nodoc: = { data: @bits[position].data, # If undefined preserve any data/reset value that has res: @bits[position].data, # already been applied at reg level }.merge() @lookup[id] = { pos: position, bits: 1, feature: [:feature] } @bits.delete_at(position) # Remove the initial bit from this position @bits.insert(position, Bit.new(self, position, )) self end |
#add_bits_from_options(options = {}) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
# File 'lib/origen/registers/reg.rb', line 409 def ( = {}) # :nodoc: # edit Traynor # options is now an array for split bit groups or a hash if single bit/range bits # Now add the requested bits to the register, removing the unwritable bits as required .each do |bit_id, bit_params| if bit_params.is_a? Hash description = bit_params.delete(:description) if description @description_from_api[bit_id] = description.split(/\r?\n/) end bind(bit_id, bit_params.delete(:bind)) if bit_params[:bind] position = bit_params[:pos] || 0 num_bits = bit_params[:bits] || 1 if @reset if @reset.is_a?(Symbol) bit_params[:res] = @reset else bit_params[:res] = @reset[(num_bits + position - 1), position] end end bit_params[:access] = @access if bit_params[:access].nil? bit_params[:res] = bit_params[:data] if bit_params[:data] bit_params[:res] = bit_params[:reset] if bit_params[:reset] if num_bits == 1 add_bit(bit_id, position, bit_params) # and add the new one else add_bus(bit_id, position, num_bits, bit_params) end elsif bit_params.is_a? Array description = bit_params.map { |h| h.delete(:description) }.compact.join("\n") unless description.empty? @description_from_api[bit_id] = description.split(/\r?\n/) end add_bus_scramble(bit_id, bit_params) end end self end |
#add_bus(id, position, size, options = {}) ⇒ Object
Add a bus to the register, should only be called internally
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 |
# File 'lib/origen/registers/reg.rb', line 838 def add_bus(id, position, size, = {}) # :nodoc: default_data = 0 size.times do |n| default_data |= @bits[position + n].data << n end = { data: default_data, # If undefined preserve any data/reset value that has res: default_data, # already been applied at reg level }.merge() @lookup[id] = { pos: position, bits: size } size.times do |n| = .dup [:data] = [:data][n] if [:res].is_a?(Symbol) [:res] = [:res] else [:res] = [:res][n] end @bits.delete_at(position + n) @bits.insert(position + n, Bit.new(self, position + n, )) end self end |
#add_bus_scramble(id, array_of_hashes = []) ⇒ Object
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 |
# File 'lib/origen/registers/reg.rb', line 862 def add_bus_scramble(id, array_of_hashes = []) array_of_hashes.each do || bind(id, .delete(:bind)) if [:bind] position = [:pos] || 0 num_bits = [:bits] || 1 size = [:bits] [:data] = [:data] if [:data] [:res] = [:reset] if [:reset] default_data = 0 size.times do |n| default_data |= @bits[position + n].data << n end = { data: default_data, # If undefined preserve any data/reset value that has res: default_data, # already been applied at reg level }.merge() @lookup[id] = [] if @lookup[id].nil? @lookup[id] = @lookup[id].push(pos: position, bits: size) size.times do |n| = .dup [:data] = [:data][n] [:res] = [:res][n] @bits.delete_at(position + n) @bits.insert(position + n, Bit.new(self, position + n, )) end self end end |
#bind(bitname, live_parameter) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/origen/registers/reg.rb', line 96 def bind(bitname, live_parameter) unless live_parameter.respond_to?(:is_a_live_parameter?) && live_parameter.is_a_live_parameter? fail 'Only live updating parameters should be bound, make sure you have not missed .live in the path to the parameter!' end @parameter_bound_bits ||= {} @parameter_bound_bits[bitname] = live_parameter end |
#bit(*args) ⇒ Object Also known as: bits, []
Returns the bit object(s) responding to the given name, wrapped in a BitCollection. This method also accepts multiple name possibilities, if neither bit exists in the register it will raise an error, otherwise it will return the first match. If no args passed in, it will return a BitCollection containing all bits. If a number is passed in then the bits from those positions are returned.
Example
add_reg :control, 0x55, :status => {:pos => 1, :bits => 2},
:fail => {:pos => 0}
reg(:control).bit(:fail) # => Returns a BitCollection containing the fail bit
reg(:control).bits(:status) # => Returns a BifCollection containing the status bits
reg(:control).bit(:bist_fail, :fail) # => Returns a BitCollection containing the fail bit
reg(:control).bit(0) # => Returns a BitCollection containing the fail bit
reg(:control).bit(1) # => Returns a BitCollection containing status bit
reg(:control).bit(1,2) # => Returns a BitCollection containing both status bits
929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 |
# File 'lib/origen/registers/reg.rb', line 929 def bit(*args) # return get_bits_with_constraint(nil,:default) if args.size == 0 constraint = extract_feature_params(args) if constraint.nil? constraint = :default end collection = BitCollection.new(self, :unknown) if args.size == 0 collection.add_name(name) @bits.each do |bit| collection << get_bits_with_constraint(bit.position, constraint) end else args.flatten! args.sort! args.each do |arg_item| if arg_item.is_a?(Fixnum) b = get_bits_with_constraint(arg_item, constraint) collection << b if b elsif arg_item.is_a?(Range) (arg_item) do |bit_number| collection << get_bits_with_constraint(bit_number, constraint) end else # Reaches here if bit name is specified if @lookup.include?(arg_item) split_bits = false @lookup.each { |_k, v| split_bits = true if v.is_a? Array } coll = get_lookup_feature_bits(arg_item, constraint, split_bits) if coll coll.each do |b| collection.add_name(arg_item) collection << b end end end end end end if collection.size == 0 # Originally Origen returned nil when asking for a bit via an index which does not # exist, e.g. reg[1000] => nil # The args numeric clause here is to maintain that behavior if Origen.config.strict_errors && !args.all? { |arg| arg.is_a?(Numeric) } puts "Register #{@name} does not have a bits(s) named :#{args.join(', :')} or it might not be enabled." puts 'This could also be a typo, these are the valid bit names:' puts @lookup.keys fail 'Missing bits error!' end nil else collection end end |
#bit_value_descriptions(bitname, options = {}) ⇒ Object
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/origen/registers/reg.rb', line 293 def bit_value_descriptions(bitname, = {}) = { format: :binary }.merge() base = case [:format] when :bin, :binary 2 when :hex, :hexadecimal 16 when :dec, :decimal 10 else fail "Unknown integer format: #{options[:format]}" end desc = {} description(bitname).each do |line| if line =~ /^\s*(\d+)\s+\|\s+(.+)/ desc[Regexp.last_match[1].to_i(base)] = Regexp.last_match[2] end end desc end |
#contains_bits? ⇒ Boolean
404 405 406 |
# File 'lib/origen/registers/reg.rb', line 404 def contains_bits? true end |
#copy(reg) ⇒ Object
Copies data and overlays from one reg object to another, it does not copy read or store flags
1165 1166 1167 1168 1169 1170 1171 1172 |
# File 'lib/origen/registers/reg.rb', line 1165 def copy(reg) size.times do |i| source_bit = reg.bit[i] @bits[i].(source_bit.) if source_bit. @bits[i].write(source_bit.data) end self end |
#copy_data_from(reg) ⇒ Object
Copies data from one reg object to another
Example
reg(:data_copy).data # => 0
reg(:data).write(0x1234)
reg(:data_copy).copy_data_from(reg(:data))
reg(:data_copy).data # => 0x1234
1156 1157 1158 1159 1160 1161 |
# File 'lib/origen/registers/reg.rb', line 1156 def copy_data_from(reg) size.times do |i| @bits[i].write(reg.bit[i].data) end self end |
#copy_overlays_from(reg, options = {}) ⇒ Object
Copy overlays from one reg object to another
Example
reg(:data_copy). # => false
reg(:data).("data_val")
reg(:data_copy).(reg(:data))
reg(:data_copy). # => true
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 |
# File 'lib/origen/registers/reg.rb', line 1136 def (reg, = {}) size.times do |i| source_bit = reg.bit[i] if source_bit. ov = source_bit. # If an id has been supplied make sure any trailing ID in the source is # changed to supplied identifier ov.gsub!(/_\d$/, "_#{options[:update_id]}") if [:update_id] @bits[i].(ov) end end self end |
#default_reg_metadata ⇒ Object
Returns any application specific metadata that has been inherited by the given register. This does not account for any overridding that may have been applied to this register specifically however, use the meta method to get that.
288 289 290 291 |
# File 'lib/origen/registers/reg.rb', line 288 def Origen::Registers..merge( Origen::Registers.[owner.class] || {}) end |
#delete_bit(collection) ⇒ Object Also known as: delete_bits
Delete the bits in the collection from the register
892 893 894 895 896 897 898 899 900 901 |
# File 'lib/origen/registers/reg.rb', line 892 def delete_bit(collection) [collection.name].flatten.each do |name| @lookup.delete(name) end collection.each do |bit| @bits.delete_at(bit.position) # Remove the bit @bits.insert(bit.position, Bit.new(self, bit.position, writable: @init_as_writable)) end self end |
#description(bitname = :_reg, options = {}) ⇒ Object Also known as: descriptions
Returns the description of this register if any, if none then an empty array will be returned
Note Adding a description field will override any comment-driven documentation of a register (ie markdown style comments)
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/origen/registers/reg.rb', line 346 def description(bitname = :_reg, = {}) bitname, = :_reg, bitname if bitname.is_a?(Hash) = { include_name: true, include_bit_values: true }.merge() if @description_from_api[bitname] desc = @description_from_api[bitname] else parse_descriptions unless description_lookup[define_file] begin desc = description_lookup[define_file][name][bitname] || [] rescue desc = [] end end desc = desc.reject do |line| if bitname != :_reg unless [:include_bit_values] !!(line =~ /^\s*(\d+)\s+\|\s+(.+)/) end else false end end if desc.first unless [:include_name] desc[0] = desc.first.sub(/\s*\*\*\s*#{escape_special_char(full_name(bitname))}\s*\*\*\s*-?\s*/, '') end end desc.shift if desc.first && desc.first.strip.empty? desc.pop if desc.last && desc.last.strip.empty? desc end |
#description_lookup ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a hash containing all register descriptions that have been parsed so far.
280 281 282 |
# File 'lib/origen/registers/reg.rb', line 280 def description_lookup @@description_lookup ||= {} end |
#empty_bits(_options = {}) ⇒ Object
Returns an array of unoccupied bit positions
Example
reg :fstat, @base + 0x0000, :size => 8 do
bit 7, :ccif
bit 6, :rdcolerr
bit 5, :accerr
bit 4, :pviol
bit 0, :mgstat0
end
regs(:fstat).empty_bits
=> [1, 2, 3]
Example
reg :aguahb2, @base + 0x2A, :size => 8 do
bit 5..2, :m0b_hbstrb, :reset => 0x0
bit 1..0, :m0b_htrans, :reset => 0x2
end
regs(:aguahb2).empty_bits
=> [6, 7]
644 645 646 647 648 |
# File 'lib/origen/registers/reg.rb', line 644 def empty_bits( = {}) array_span = (0..(size - 1)).to_a empty_bits = array_span - used_bits empty_bits end |
#empty_bits?(_options = {}) ⇒ Boolean
Returns true if any named_bits exist, false if used_bits is an empty array
651 652 653 |
# File 'lib/origen/registers/reg.rb', line 651 def empty_bits?( = {}) empty_bits.size > 0 end |
#enabled? ⇒ Boolean
Query the owner heirarchy to see if this register is enabled
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 |
# File 'lib/origen/registers/reg.rb', line 1265 def enabled? if feature value = false current_owner = self if feature.class == Array feature.each do |f| current_owner = self loop do if current_owner.respond_to?(:owner) current_owner = current_owner.owner if current_owner.respond_to?(:has_feature?) if current_owner.has_feature?(f) value = true break end end else # if current owner does not have a owner value = false break end end # loop end unless value if Origen.top_level && \ Origen.top_level.respond_to?(:has_feature?) && \ Origen.top_level.has_feature?(f) value = true unless value break end end end unless value break # break if feature not found and return false end end # iterated through all features in array return value else # if feature.class != Array loop do if current_owner.respond_to?(:owner) current_owner = current_owner.owner if current_owner.respond_to?(:has_feature?) if current_owner.has_feature?(feature) value = true break end end else # if current owner does not have a owner value = false break end end # loop end unless value if Origen.top_level && \ Origen.top_level.respond_to?(:has_feature?) && \ Origen.top_level.has_feature?(feature) value = true end end return value end else return true end end |
#enabled_by_feature?(name = nil) ⇒ Boolean Also known as: has_feature_constraint?
Returns true if the register is constrained by the given/any feature
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 |
# File 'lib/origen/registers/reg.rb', line 1246 def enabled_by_feature?(name = nil) if !name !!feature else if feature.class == Array feature.each do |f| if f == name return true end end return false else return feature == name end end end |
#escape_special_char(str) ⇒ Object
Escapes brackets and parenthesis. Helper for description method.
337 338 339 |
# File 'lib/origen/registers/reg.rb', line 337 def escape_special_char(str) str.gsub('[', '\[').gsub(']', '\]').gsub('(', '\(').gsub(')', '\)') if str end |
#expand_range(range) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
905 906 907 908 909 910 911 912 |
# File 'lib/origen/registers/reg.rb', line 905 def (range) if range.first > range.last range = Range.new(range.last, range.first) end range.each do |i| yield i end end |
#extract_feature_params(args) ⇒ Object
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
# File 'lib/origen/registers/reg.rb', line 1091 def extract_feature_params(args) index = args.find_index { |arg| arg.class == Hash } if index params = args.delete_at(index) else params = nil end if params return params[:enabled_features] || params[:enabled_feature] else return nil end end |
#extract_meta_data(method, *args) ⇒ Object
1236 1237 1238 1239 1240 1241 1242 1243 |
# File 'lib/origen/registers/reg.rb', line 1236 def (method, *args) method = method.to_s.sub('?', '') if method =~ /=/ instance_variable_set("@#{method.sub('=', '')}", args.first) else instance_variable_get("@#{method}") || [method.to_sym] end end |
#freeze ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/origen/registers/reg.rb', line 88 def freeze bits.each(&:freeze) # Call any methods which cache results to generate the instance variables # before they are frozen address super end |
#full_name(bitname = :_reg, _options = {}) ⇒ Object
Returns the full name of the register when this has been specified in the register description like this:
# ** This is the Register Full Name **
# This register blah blah
This method will also be called by bit collections to look up the name when defined in a similar manner in the bit description.
If no name has been specified this will return nil.
326 327 328 329 330 331 332 333 334 |
# File 'lib/origen/registers/reg.rb', line 326 def full_name(bitname = :_reg, = {}) bitname, = :_reg, bitname if bitname.is_a?(Hash) desc = description(bitname).first # Capture something like this: # ** This is the full name ** - This bit blah blah if desc && desc =~ /\s*\*\*\s*([^\*.]*)\s*\*\*/ Regexp.last_match[1].strip end end |
#get_bits_with_constraint(number, params) ⇒ Object
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 |
# File 'lib/origen/registers/reg.rb', line 987 def get_bits_with_constraint(number, params) return nil unless @bits[number] if (params == :default || !params) && @bits[number].enabled? @bits[number] elsif params == :none && !@bits[number].has_feature_constraint? @bits[number] elsif params == :all @bits[number] elsif params.class == Array params.each do |param| unless @bits[number].enabled_by_feature?(param) return nil end @bits[number] end elsif @bits[number].enabled_by_feature?(params) @bits[number] else return Bit.new(self, number, writable: false) end end |
#get_lookup_feature_bits(bit_name, params, split_group_reg) ⇒ Object
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
# File 'lib/origen/registers/reg.rb', line 1009 def get_lookup_feature_bits(bit_name, params, split_group_reg) ## if split_group_reg == false # if this register has single bits and continuous ranges if @lookup.include?(bit_name) collection = BitCollection.new(self, bit_name) (@lookup[bit_name][:bits]).times do |i| collection << @bits[@lookup[bit_name][:pos] + i] end if !params || params == :default if collection.enabled? return collection end elsif params == :none unless collection.has_feature_constraint? return collection end elsif params == :all return collection elsif params.class == Array if params.all? { |param| collection.enabled_by_feature?(param) } return collection end else if collection.enabled_by_feature?(params) return collection end end return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name][:pos]) else return [] end elsif split_group_reg == true # if this registers has split bits in its range if @lookup.is_a?(Hash) # && @lookup.include?(bit_name) collection = false @lookup.each do |k, v| # k is the bitname, v is the hash of bit data if k == bit_name collection ||= BitCollection.new(self, k) if v.is_a?(Array) v.reverse_each do |pb| # loop each piece of bit group data (pb[:bits]).times do |i| collection << @bits[pb[:pos] + i] end end else (v[:bits]).times do |i| collection << @bits[v[:pos] + i] end end end end if !params || params == :default if collection.enabled? return collection end elsif params == :none unless collection.has_feature_constraint? return collection end elsif params == :all return collection elsif params.class == Array if params.all? { |param| collection.enabled_by_feature?(param) } return collection end else if collection.enabled_by_feature?(params) return collection end end if @lookup.is_a?(Hash) && @lookup[bit_name].is_a?(Array) return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name][0][:pos]) else return BitCollection.dummy(self, bit_name, size: collection.size, pos: @lookup[bit_name[:pos]]) end else return [] end end end |
#has_bit?(name) ⇒ Boolean Also known as: has_bits?, has_bit, has_bits
Returns true if the register contains a bit(s) matching the given name
Example
add_reg :control, 0x55, :status => {:pos => 1}
reg(:control).has_bit?(:result) # => false
reg(:control).has_bit?(:status) # => true
817 818 819 |
# File 'lib/origen/registers/reg.rb', line 817 def has_bit?(name) @lookup.include?(name) end |
#has_bits_enabled_by_feature?(name = nil) ⇒ Boolean
Returns true if any of the bits within this register has feature associated with it.
1332 1333 1334 1335 1336 1337 1338 |
# File 'lib/origen/registers/reg.rb', line 1332 def has_bits_enabled_by_feature?(name = nil) if !name bits.any?(&:has_feature_constraint?) else bits.any? { |bit| bit.enabled_by_feature?(name) } end end |
#has_parameter_bound_bits? ⇒ Boolean
104 105 106 |
# File 'lib/origen/registers/reg.rb', line 104 def has_parameter_bound_bits? @parameter_bound_bits && !@parameter_bound_bits.empty? end |
#initialize_copy(orig) ⇒ Object
This method is called whenever reg.clone is called to make a copy of a given register. Ruby will correctly copy all instance variables but it will not drill down to copy nested attributes, like the bits contained in @bits. This function will therefore correctly clone all bits contained in the register also.
453 454 455 456 457 458 459 460 |
# File 'lib/origen/registers/reg.rb', line 453 def initialize_copy(orig) # :nodoc: @bits = [] orig.bits.each do |bit| @bits << bit.clone end @lookup = orig.lookup.clone self end |
#inspect ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 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 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 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 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/origen/registers/reg.rb', line 120 def inspect bit_width = 13 desc = ["\n0x%X - :#{name}" % address] desc << ' ' + ('=' * (bit_width + 1) * 8) # "<#{self.class}: #{self.name}>" (size / 8).times do |byte_index| # Need to add support for little endian regs here? byte_number = (size / 8) - byte_index max_bit = size - (byte_index * 8) - 1 min_bit = max_bit - 8 + 1 line = ' ' # BIT INDEX ROW 8.times do |i| line << '|' + "#{size - i - 1 - (byte_index * 8)}".center(bit_width) end line += '|' desc << line # BIT NAME ROW line = ' ' named_bits include_spacers: true do |name, bit, bitcounter| if _bit_in_range?(bit, max_bit, min_bit) if bit.size > 1 if name if bitcounter.nil? bit_name = "#{name}[#{_max_bit_in_range(bit, max_bit, min_bit)}:#{_min_bit_in_range(bit, max_bit, min_bit)}]" bit_span = _num_bits_in_range(bit, max_bit, min_bit) else upper = _max_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size lower = _min_bit_in_range(bit, max_bit, min_bit) + bitcounter - bit.size bit_name = "#{name}[#{upper}:#{lower}]" bit_span = upper - lower + 1 end width = bit_width * bit_span line << '|' + ":#{bit_name[0..width - 2]}".center(width + bit_span - 1) else bit.shift_out_left do |bit| if _index_in_range?(bit.position, max_bit, min_bit) line << '|' + ''.center(bit_width) end end end else bit_name = "#{name}" line << '|' + ":#{bit_name[0..bit_width - 2]}".center(bit_width) end end end line += '|' desc << line ## BIT ACCESS ROW # line = "Access " # self.named_bits :include_spacers => true do |name, bit| # if _bit_in_range?(bit, max_bit, min_bit) # if bit.size > 1 # if name # access = _bit_rw(bit) # bit_span = _num_bits_in_range(bit, max_bit, min_bit) # width = bit_width * bit_span # line << "|" + access.center(width + bit_span - 1) # else # bit.shift_out_left do |bit| # if _index_in_range?(bit.position, max_bit, min_bit) # line << "|" + "".center(bit_width) # end # end # end # else # access = _bit_rw(bit) # line << "|" + access.center(bit_width) # end # end # end # line += "|" # desc << line ## BIT RESET ROW # line = "Reset " # self.named_bits :include_spacers => true do |name, bit| # if _bit_in_range?(bit, max_bit, min_bit) # if bit.size > 1 # if name # value = "0x%X" % bit.reset_val[_max_bit_in_range(bit, max_bit, min_bit).._min_bit_in_range(bit, max_bit, min_bit)] # bit_span = _num_bits_in_range(bit, max_bit, min_bit) # width = bit_width * bit_span # line << "|" + value.center(width + bit_span - 1) # else # bit.shift_out_left do |bit| # if _index_in_range?(bit.position, max_bit, min_bit) # line << "|" + "".center(bit_width) # end # end # end # else # line << "|" + "#{bit.reset_val}".center(bit_width) # end # end # end # line += "|" # desc << line # BIT STATE ROW line = ' ' named_bits include_spacers: true do |name, bit, _bitcounter| if _bit_in_range?(bit, max_bit, min_bit) if bit.size > 1 if name if bit.has_known_value? value = '0x%X' % bit.val[_max_bit_in_range(bit, max_bit, min_bit).._min_bit_in_range(bit, max_bit, min_bit)] else if bit.reset_val == :undefined value = 'X' else value = 'M' end end value += _state_desc(bit) bit_span = _num_bits_in_range(bit, max_bit, min_bit) width = bit_width * bit_span line << '|' + value.center(width + bit_span - 1) else bit.shift_out_left do |bit| if _index_in_range?(bit.position, max_bit, min_bit) line << '|' + ''.center(bit_width) end end end else if bit.has_known_value? val = bit.val else if bit.reset_val == :undefined val = 'X' else val = 'M' end end value = "#{val}" + _state_desc(bit) line << '|' + value.center(bit_width) end end end line += '|' desc << line desc << ' ' + ('-' * (bit_width + 1) * 8) end desc.join("\n") end |
#lookup_operation_handler(operation) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
679 680 681 682 683 684 685 686 687 688 689 690 |
# File 'lib/origen/registers/reg.rb', line 679 def lookup_operation_handler(operation) # Could have made the controller be the owner when assigned above, but may have run # into problems with the reg meta data stuff reg_owner = owner.respond_to?(:controller) && owner.controller ? owner.controller : owner if reg_owner.respond_to?(operation) reg_owner elsif reg_owner.respond_to?(:owner) && reg_owner.owner.respond_to?(operation) reg_owner.owner elsif Origen.top_level && Origen.top_level.respond_to?(operation) Origen.top_level end end |
#meta_data_method?(method) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 |
# File 'lib/origen/registers/reg.rb', line 1223 def (method) attr_name = method.to_s.gsub(/\??=?/, '').to_sym if .key?(attr_name) if method.to_s =~ /\?/ [true, false].include?([attr_name]) else true end else false end end |
#named_bits(options = {}) ⇒ Object
Returns each named bit collection contained in the register,
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/origen/registers/reg.rb', line 474 def named_bits( = {}) = { include_spacers: false }.merge() # test if @lookup has any values stored as an array # if so it means there is a split group of bits # process that differently to a single bit or continuous range of bits # which are typically stored in a hash split_bits = false @lookup.each { |_k, v| split_bits = true if v.is_a? Array } if split_bits == false current_pos = size # Sort by position descending @lookup.sort_by { |_name, details| -details[:pos] }.each do |name, details| pos = details[:bits] + details[:pos] if [:include_spacers] && (pos != current_pos) collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos) yield nil, collection end collection = BitCollection.new(self, name) details[:bits].times do |i| collection << @bits[details[:pos] + i] end yield name, collection current_pos = details[:pos] end if [:include_spacers] && current_pos != 0 collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0) yield nil, collection end elsif split_bits == true # if there are split bits, need to convert all regsiter bit values to array elements to allow sorting # if the register has bits split up across it, then store the bits in order of decreasing reg position # but first, stuff all the bits in a simple array, as single bits, or ranges of bits @lookup_splits = [] @lookup.each do |k, v| tempbit = {} bitcounter = {} if v.is_a? Hash # then this is already a single bit or a continuous range so just stuff it into the array tempbit[k] = v @lookup_splits << tempbit.clone elsif v.is_a? Array # if the bitgroup is split, then decompose into single bits and continuous ranges v.each_with_index do |bitdetail, _i| if bitcounter.key?(k) bitcounter[k] = bitcounter[k] + bitdetail[:bits] else bitcounter[k] = bitdetail[:bits] end tempbit[k] = bitdetail @lookup_splits << tempbit.clone end end if v.is_a? Array @lookup_splits.each_with_index do |_e, q| groupname = @lookup_splits[q].to_a[0][0] if groupname == k @lookup_splits[q][groupname][:bitgrouppos] = bitcounter[groupname] if groupname == k bitcounter[groupname] = bitcounter[groupname] - @lookup_splits[q][groupname][:bits] end end end end # Now sort the array in descending order # Does adding the bitgrouppos need to happen after the sort ? @lookup_splits = @lookup_splits.sort do |a, b| b.to_a[0][1][:pos] <=> a.to_a[0][1][:pos] end current_pos = size countbits = {} # if countbits.method == nil @master = {} bitgroup = {} bitinfo = {} info = {} @lookup_splits.each_with_index do |hash, _i| name = hash.to_a[0][0] details = hash.to_a[0][1] bitcounter = hash.to_a[0][1][:bitgrouppos] pos = details[:bits] + details[:pos] if [:include_spacers] && (pos != current_pos) collection = BitCollection.dummy(self, nil, size: current_pos - pos, pos: pos) yield nil, collection, bitcounter end collection = BitCollection.new(self, name) details[:bits].times do |i| collection << @bits[details[:pos] + i] end yield name, collection, bitcounter current_pos = details[:pos] end if [:include_spacers] && current_pos != 0 collection = BitCollection.dummy(self, nil, size: current_pos, pos: 0) yield nil, collection, bitcounter end end end |
#offset ⇒ Object
Returns the relative address of the given register, equivalent to calling reg.address(:relative => true)
694 695 696 |
# File 'lib/origen/registers/reg.rb', line 694 def offset address(relative: true) end |
#owned_by?(name) ⇒ Boolean
Returns true if the register owner matches the given name. A match will be detected if the class names of the register’s owner contains the given name.
Alternatively if the register owner implements a method called reg_owner_alias then the value that this returns instead will also be considered when checking if the given name matches. This method can return an array of names if multiple aliases are required.
Aliases can be useful for de-coupling the commonly used name, e.g. “NVM” from the actual class name.
799 800 801 802 803 804 805 806 807 808 809 |
# File 'lib/origen/registers/reg.rb', line 799 def owned_by?(name) !!(owner.class.to_s =~ /#{name}/i) || begin if owner.respond_to?(:reg_owner_alias) [owner.reg_owner_alias].flatten.any? do |al| al.to_s =~ /#{name}/i end else false end end end |
#parse_descriptions ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# File 'lib/origen/registers/reg.rb', line 383 def parse_descriptions desc = [] File.readlines(define_file).each do |line| if line =~ /^\s*#(.*)/ desc << Regexp.last_match[1].strip elsif line =~ /^\s*(add_reg|reg)\(?\s*:(\w+)\s*,.*do/ @current_reg_name = Regexp.last_match[2].to_sym description_lookup[define_file] ||= {} description_lookup[define_file][@current_reg_name] ||= {} description_lookup[define_file][@current_reg_name][:_reg] = desc.dup desc = [] # http://www.rubular.com/r/7FidbC1JRA elsif @current_reg_name && line =~ /^\s*(add_bit|bit|reg\.bit)s?\(?\s*\d+\.?\.?\d*\s*,\s*:(\w+)/ description_lookup[define_file][@current_reg_name][Regexp.last_match[2].to_sym] = desc.dup desc = [] else desc = [] end end end |
#reader ⇒ Object
Returns the object that will be responsible for reading the given register
674 675 676 |
# File 'lib/origen/registers/reg.rb', line 674 def reader @reader ||= lookup_operation_handler(:read_register) end |
#request(operation, options = {}) ⇒ Object
Proxies requests from bit collections to the register owner
656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/origen/registers/reg.rb', line 656 def request(operation, = {}) # :nodoc: if operation == :read_register object = reader owner.read_register_missing!(self) unless object else object = writer owner.write_register_missing!(self) unless object end object.send(operation, self, ) self end |
#respond_to?(sym) ⇒ Boolean
Recognize that Reg responds to all BitCollection methods methods based on application-specific meta data properties
1125 1126 1127 1128 |
# File 'lib/origen/registers/reg.rb', line 1125 def respond_to?(sym) # :nodoc: sym = sym.to_sym (sym) || has_bits?(sym) || super(sym) || BitCollection.instance_methods.include?(sym) end |
#reverse_named_bits(_options = {}) ⇒ Object
Returns each named bit collection contained in self
580 581 582 583 584 585 586 |
# File 'lib/origen/registers/reg.rb', line 580 def reverse_named_bits( = {}) bits = [] named_bits { |name, bit| bits << [name, bit] } bits.each do |bit| yield bit[0], bit[1] end end |
#update_bound_bits ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/origen/registers/reg.rb', line 108 def update_bound_bits @updating_bound_bits = true @parameter_bound_bits.each do |name, val| bits(name).write(val) end @updating_bound_bits = false end |
#updating_bound_bits? ⇒ Boolean
116 117 118 |
# File 'lib/origen/registers/reg.rb', line 116 def updating_bound_bits? @updating_bound_bits end |
#used_bits(_options = {}) ⇒ Object
Returns an array of occupied bit positions
Example
reg :fstat, @base + 0x0000, :size => 8 do
bit 7, :ccif
bit 6, :rdcolerr
bit 5, :accerr
bit 4, :pviol
bit 0, :mgstat0
end
regs(:fstat).used_bits
=> [0, 4, 5, 6, 7]
Example
reg :aguahb2, @base + 0x2A, :size => 8 do
bit 5..2, :m0b_hbstrb, :reset => 0x0
bit 1..0, :m0b_htrans, :reset => 0x2
end
regs(:aguahb2).used_bits
=> [0, 1, 2, 3, 4, 5]
607 608 609 610 611 612 613 614 615 616 617 618 |
# File 'lib/origen/registers/reg.rb', line 607 def used_bits( = {}) used_bits = [] named_bits do |_name, bit| used_bits << bit.position if bit.size == 1 if bit.size > 1 used_bits << ((bit.position)..(bit.position + bit.size - 1)).to_a end end used_bits.flatten! used_bits.sort! used_bits end |
#used_bits?(_options = {}) ⇒ Boolean
Returns true if any named_bits exist, false if used_bits is an empty array
621 622 623 |
# File 'lib/origen/registers/reg.rb', line 621 def used_bits?( = {}) used_bits.size > 0 end |
#writer ⇒ Object
Returns the object that will be responsible for writing the given register
669 670 671 |
# File 'lib/origen/registers/reg.rb', line 669 def writer @writer ||= lookup_operation_handler(:write_register) end |
#|(val) ⇒ Object
Returns the BITWISE OR of reg with another reg or a number, the state of both registers remains unchanged
1187 1188 1189 |
# File 'lib/origen/registers/reg.rb', line 1187 def |(val) data | Reg.clean_value(val) end |