Module: Udb::HasFields
Overview
Shared field-management methods for register-like objects (CSR, MMR).
Includers must provide:
- length(effective_xlen) — register width in bits
- max_length — largest possible width
- cfg_arch — ConfiguredArchitecture
- name — register name (String)
- defined_by_condition — ExtensionRequirement condition
- exists_in_cfg?(cfg_arch)
Instance Method Summary collapse
-
#affected_by?(ext_ver) ⇒ Boolean
Whether or not the presence of ext_ver affects this register definition.
-
#field(field_name) ⇒ CsrField?
Field named ‘field_name’ if it exists, and nil otherwise.
-
#field?(field_name) ⇒ Boolean
True if a field named ‘field_name’ is defined.
-
#field_hash ⇒ Hash<String,CsrField>
Hash of fields, indexed by field name.
-
#fields ⇒ Array<CsrField>
All known fields of this register.
-
#fields_for(effective_xlen) ⇒ Array<CsrField>
All known fields when XLEN ==
effective_xlen. -
#optional_in_cfg?(cfg_arch) ⇒ Boolean
Whether or not the register is optional in the config.
-
#possible_fields ⇒ Array<CsrField>
All implemented fields, excluding fields defined by unimplemented extensions.
-
#possible_fields_for(effective_xlen) ⇒ Array<CsrField>
All implemented fields at the given effective XLEN.
-
#wavedrom_desc(cfg_arch, effective_xlen, exclude_unimplemented: false, optional_type: 2) ⇒ Hash
A representation of the WaveDrom drawing for the register.
-
#writable ⇒ Boolean
Whether or not the register can be written by software.
Instance Method Details
#affected_by?(ext_ver) ⇒ Boolean
Returns Whether or not the presence of ext_ver affects this register definition.
145 146 147 148 |
# File 'lib/udb/obj/has_fields.rb', line 145 def affected_by?(ext_ver) defined_by_condition.satisfiability_depends_on_ext_req?(ext_ver.to_ext_req) || \ fields.any? { |field| field.affected_by?(ext_ver) } end |
#field(field_name) ⇒ CsrField?
Returns field named ‘field_name’ if it exists, and nil otherwise.
56 57 58 |
# File 'lib/udb/obj/has_fields.rb', line 56 def field(field_name) field_hash[field_name.to_s] end |
#field?(field_name) ⇒ Boolean
Returns true if a field named ‘field_name’ is defined.
51 52 53 |
# File 'lib/udb/obj/has_fields.rb', line 51 def field?(field_name) field_hash.key?(field_name.to_s) end |
#field_hash ⇒ Hash<String,CsrField>
Returns Hash of fields, indexed by field name.
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/udb/obj/has_fields.rb', line 39 def field_hash @field_hash unless @field_hash.nil? @field_hash = {} fields.each do |field| @field_hash[field.name] = field end @field_hash end |
#fields ⇒ Array<CsrField>
Returns All known fields of this register.
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/udb/obj/has_fields.rb', line 21 def fields return @fields unless @fields.nil? @fields = if @data["fields"].nil? [] else @data["fields"].map { |field_name, field_data| CsrField.new(self, field_name, field_data) } end end |
#fields_for(effective_xlen) ⇒ Array<CsrField>
Returns All known fields when XLEN == effective_xlen.
34 35 36 |
# File 'lib/udb/obj/has_fields.rb', line 34 def fields_for(effective_xlen) fields.select { |f| effective_xlen.nil? || f.base.nil? || f.base == effective_xlen } end |
#optional_in_cfg?(cfg_arch) ⇒ Boolean
Returns whether or not the register is optional in the config.
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/udb/obj/has_fields.rb', line 133 def optional_in_cfg?(cfg_arch) unless cfg_arch.is_a?(ConfiguredArchitecture) raise ArgumentError, "cfg_arch is a class #{cfg_arch.class} but must be a ConfiguredArchitecture" end raise "optional_in_cfg? should only be used by a partially-specified arch def" unless cfg_arch.partially_configured? @optional_in_cfg ||= exists_in_cfg?(cfg_arch) && (defined_by_condition.satisfied_by_cfg_arch?(cfg_arch) == SatisfiedResult::Maybe) end |
#possible_fields ⇒ Array<CsrField>
Returns All implemented fields, excluding fields defined by unimplemented extensions.
61 62 63 64 65 |
# File 'lib/udb/obj/has_fields.rb', line 61 def possible_fields @possible_fields ||= fields.select do |f| f.exists_in_cfg?(cfg_arch) end end |
#possible_fields_for(effective_xlen) ⇒ Array<CsrField>
Returns All implemented fields at the given effective XLEN.
69 70 71 72 73 74 75 76 77 |
# File 'lib/udb/obj/has_fields.rb', line 69 def possible_fields_for(effective_xlen) raise ArgumentError, "effective_xlen is non-nil and is a #{effective_xlen.class} but must be an Integer" unless effective_xlen.nil? || effective_xlen.is_a?(Integer) @possible_fields_for ||= {} @possible_fields_for[effective_xlen] ||= possible_fields.select do |f| f.base.nil? || f.base == effective_xlen end end |
#wavedrom_desc(cfg_arch, effective_xlen, exclude_unimplemented: false, optional_type: 2) ⇒ Hash
Returns A representation of the WaveDrom drawing for the register.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/udb/obj/has_fields.rb', line 89 def wavedrom_desc(cfg_arch, effective_xlen, exclude_unimplemented: false, optional_type: 2) unless cfg_arch.is_a?(ConfiguredArchitecture) raise ArgumentError, "cfg_arch is a class #{cfg_arch.class} but must be a ConfiguredArchitecture" end raise ArgumentError, "effective_xlen is non-nil and is a #{effective_xlen.class} but must be an Integer" unless effective_xlen.nil? || effective_xlen.is_a?(Integer) desc = { "reg" => [] } last_idx = -1 field_list = if exclude_unimplemented possible_fields_for(effective_xlen) else fields_for(effective_xlen) end field_list.sort! { |a, b| a.location(effective_xlen).min <=> b.location(effective_xlen).min } field_list.each do |field| if field.location(effective_xlen).min != last_idx + 1 # reserved space n = field.location(effective_xlen).min - last_idx - 1 raise "negative reserved space? #{n} #{name} #{field.location(effective_xlen).min} #{last_idx + 1}" if n <= 0 desc["reg"] << { "bits" => n, type: 1 } end if cfg_arch.partially_configured? && field.optional_in_cfg?(cfg_arch) desc["reg"] << { "bits" => field.location(effective_xlen).size, "name" => field.name, type: optional_type } else desc["reg"] << { "bits" => field.location(effective_xlen).size, "name" => field.name, type: 3 } end last_idx = field.location(effective_xlen).max end if !field_list.empty? && (field_list.last.location(effective_xlen).max != (length(effective_xlen) - 1)) desc["reg"] << { "bits" => (length(effective_xlen) - 1 - last_idx), type: 1 } end desc["config"] = { "bits" => length(effective_xlen) } desc["config"]["lanes"] = length(effective_xlen) / 16 desc end |
#writable ⇒ Boolean
Returns Whether or not the register can be written by software.
80 81 82 |
# File 'lib/udb/obj/has_fields.rb', line 80 def writable @data["writable"] end |