rggen-default-register-map 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +74 -0
  3. data/LICENSE +21 -0
  4. data/README.md +45 -0
  5. data/lib/rggen/default_register_map.rb +46 -0
  6. data/lib/rggen/default_register_map/bit_field/bit_assignment.rb +122 -0
  7. data/lib/rggen/default_register_map/bit_field/comment.rb +18 -0
  8. data/lib/rggen/default_register_map/bit_field/initial_value.rb +75 -0
  9. data/lib/rggen/default_register_map/bit_field/name.rb +37 -0
  10. data/lib/rggen/default_register_map/bit_field/reference.rb +142 -0
  11. data/lib/rggen/default_register_map/bit_field/type.rb +117 -0
  12. data/lib/rggen/default_register_map/bit_field/type/rc.rb +9 -0
  13. data/lib/rggen/default_register_map/bit_field/type/reserved.rb +8 -0
  14. data/lib/rggen/default_register_map/bit_field/type/ro.rb +8 -0
  15. data/lib/rggen/default_register_map/bit_field/type/rof.rb +9 -0
  16. data/lib/rggen/default_register_map/bit_field/type/rs.rb +8 -0
  17. data/lib/rggen/default_register_map/bit_field/type/rw.rb +9 -0
  18. data/lib/rggen/default_register_map/bit_field/type/rwc.rb +9 -0
  19. data/lib/rggen/default_register_map/bit_field/type/rwe_rwl.rb +10 -0
  20. data/lib/rggen/default_register_map/bit_field/type/w0c_w1c.rb +9 -0
  21. data/lib/rggen/default_register_map/bit_field/type/w0s_w1s.rb +8 -0
  22. data/lib/rggen/default_register_map/bit_field/type/w0trg_w1trg.rb +8 -0
  23. data/lib/rggen/default_register_map/bit_field/type/wo.rb +9 -0
  24. data/lib/rggen/default_register_map/global/address_width.rb +34 -0
  25. data/lib/rggen/default_register_map/global/bus_width.rb +35 -0
  26. data/lib/rggen/default_register_map/register/name.rb +36 -0
  27. data/lib/rggen/default_register_map/register/offset_address.rb +106 -0
  28. data/lib/rggen/default_register_map/register/size.rb +95 -0
  29. data/lib/rggen/default_register_map/register/type.rb +135 -0
  30. data/lib/rggen/default_register_map/register/type/external.rb +16 -0
  31. data/lib/rggen/default_register_map/register/type/indirect.rb +256 -0
  32. data/lib/rggen/default_register_map/register_block/byte_size.rb +61 -0
  33. data/lib/rggen/default_register_map/register_block/name.rb +38 -0
  34. data/lib/rggen/default_register_map/setup.rb +18 -0
  35. data/lib/rggen/default_register_map/version.rb +7 -0
  36. metadata +95 -0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register, :name) do
4
+ register_map do
5
+ property :name
6
+
7
+ input_pattern variable_name
8
+
9
+ build do |value|
10
+ @name =
11
+ if pattern_matched?
12
+ match_data.to_s
13
+ else
14
+ error "illegal input value for register name: #{value.inspect}"
15
+ end
16
+ end
17
+
18
+ verify(:feature) do
19
+ error_condition { !name }
20
+ message { 'no register name is given' }
21
+ end
22
+
23
+ verify(:feature) do
24
+ error_condition { duplicated_name? }
25
+ message { "duplicated register name: #{name}" }
26
+ end
27
+
28
+ printable :name
29
+
30
+ private
31
+
32
+ def duplicated_name?
33
+ register_block.registers.any? { |register| register.name == name }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register, :offset_address) do
4
+ register_map do
5
+ property :offset_address
6
+ property :address_range, initial: -> { start_address..end_address }
7
+ property :overlap?, forward_to: :overlap_address_range?
8
+
9
+ build do |value|
10
+ @offset_address =
11
+ begin
12
+ Integer(value)
13
+ rescue ArgumentError, TypeError
14
+ error "cannot convert #{value.inspect} into offset address"
15
+ end
16
+ end
17
+
18
+ verify(:feature) do
19
+ error_condition { !offset_address }
20
+ message { 'no offset address is given' }
21
+ end
22
+
23
+ verify(:feature) do
24
+ error_condition { offset_address.negative? }
25
+ message { "offset address is less than 0: #{offset_address}" }
26
+ end
27
+
28
+ verify(:feature) do
29
+ error_condition { (offset_address % byte_width).positive? }
30
+ message do
31
+ "offset address is not aligned with bus width(#{bus_width}): "\
32
+ "0x#{offset_address.to_s(16)}"
33
+ end
34
+ end
35
+
36
+ verify(:component) do
37
+ error_condition { end_address > register_block.byte_size }
38
+ message do
39
+ 'offset address range exceeds byte size of register block' \
40
+ "(#{register_block.byte_size}): " \
41
+ "0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
42
+ end
43
+ end
44
+
45
+ verify(:component) do
46
+ error_condition do
47
+ register_block.registers.any? do |register|
48
+ overlap_address_range?(register) &&
49
+ support_unique_range_only?(register)
50
+ end
51
+ end
52
+ message do
53
+ 'offset address range overlaps with other offset address range: ' \
54
+ "0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
55
+ end
56
+ end
57
+
58
+ printable(:offset_address) do
59
+ [start_address, end_address]
60
+ .map(&method(:printable_address)).join(' - ')
61
+ end
62
+
63
+ private
64
+
65
+ def bus_width
66
+ configuration.bus_width
67
+ end
68
+
69
+ def byte_width
70
+ configuration.byte_width
71
+ end
72
+
73
+ def start_address
74
+ offset_address
75
+ end
76
+
77
+ def end_address
78
+ start_address + register.byte_size - 1
79
+ end
80
+
81
+ def overlap_address_range?(other_register)
82
+ overlap_range?(other_register) && match_access?(other_register)
83
+ end
84
+
85
+ def overlap_range?(other_register)
86
+ own = address_range
87
+ other = other_register.address_range
88
+ own.include?(other.first) || other.include?(own.first)
89
+ end
90
+
91
+ def match_access?(other_register)
92
+ (register.writable? && other_register.writable?) ||
93
+ (register.readable? && other_register.readable?)
94
+ end
95
+
96
+ def support_unique_range_only?(other_register)
97
+ !(register.settings[:support_overlapped_address] &&
98
+ register.match_type?(other_register))
99
+ end
100
+
101
+ def printable_address(address)
102
+ print_width = (register_block.local_address_width + 3) / 4
103
+ format('0x%0*x', print_width, address)
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register, :size) do
4
+ register_map do
5
+ property :size
6
+ property :width, initial: -> { calc_width }
7
+ property :byte_width, initial: -> { width / 8 }
8
+ property :byte_size, initial: -> { calc_byte_size }
9
+ property :array?, forward_to: :array_register?
10
+ property :array_size, forward_to: :array_registers
11
+ property :count, initial: -> { calc_count }
12
+
13
+ input_pattern [
14
+ /(#{integer}(:?,#{integer})*)/,
15
+ /\[(#{integer}(:?,#{integer})*)\]/
16
+ ], match_automatically: false
17
+
18
+ build do |values|
19
+ @size = parse_values(values)
20
+ end
21
+
22
+ verify(:feature) do
23
+ error_condition { size && !size.all?(&:positive?) }
24
+ message do
25
+ "non positive value(s) are not allowed for register size: #{size}"
26
+ end
27
+ end
28
+
29
+ printable(:array_size) do
30
+ (array_register? || nil) && "[#{array_registers.join(', ')}]"
31
+ end
32
+
33
+ private
34
+
35
+ def parse_values(values)
36
+ Array(
37
+ values.is_a?(String) && parse_string_values(values) || values
38
+ ).map(&method(:convert_value))
39
+ end
40
+
41
+ def parse_string_values(values)
42
+ if match_pattern(values)
43
+ split_match_data(match_data)
44
+ else
45
+ error "illegal input value for register size: #{values.inspect}"
46
+ end
47
+ end
48
+
49
+ def split_match_data(match_data)
50
+ match_data.captures.first.split(',')
51
+ end
52
+
53
+ def convert_value(value)
54
+ Integer(value)
55
+ rescue ArgumentError, TypeError
56
+ error "cannot convert #{value.inspect} into register size"
57
+ end
58
+
59
+ def calc_width
60
+ bus_width = configuration.bus_width
61
+ if register.bit_fields.empty?
62
+ bus_width
63
+ else
64
+ ((max_msb + bus_width) / bus_width) * bus_width
65
+ end
66
+ end
67
+
68
+ def max_msb
69
+ register
70
+ .bit_fields
71
+ .map { |bit_field| bit_field.msb((bit_field.sequence_size || 1) - 1) }
72
+ .max
73
+ end
74
+
75
+ def calc_byte_size
76
+ if register.settings[:byte_size]
77
+ instance_exec(&register.settings[:byte_size])
78
+ else
79
+ Array(@size).reduce(1, :*) * byte_width
80
+ end
81
+ end
82
+
83
+ def array_register?
84
+ register.settings[:support_array] && !@size.nil? || false
85
+ end
86
+
87
+ def array_registers
88
+ array_register? && @size || nil
89
+ end
90
+
91
+ def calc_count
92
+ Array(array_registers).reduce(1, :*)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_feature(:register, :type) do
4
+ register_map do
5
+ base_feature do
6
+ define_helpers do
7
+ def writable?(&block)
8
+ @writability = block
9
+ end
10
+
11
+ def readable?(&block)
12
+ @readability = block
13
+ end
14
+
15
+ attr_reader :writability
16
+ attr_reader :readability
17
+
18
+ def no_bit_fields
19
+ @no_bit_fields = true
20
+ end
21
+
22
+ def need_bit_fields?
23
+ !@no_bit_fields
24
+ end
25
+
26
+ def settings
27
+ @settings ||= {}
28
+ end
29
+
30
+ def support_array_register
31
+ settings[:support_array] = true
32
+ end
33
+
34
+ def byte_size(&block)
35
+ settings[:byte_size] = block
36
+ end
37
+
38
+ def support_overlapped_address
39
+ settings[:support_overlapped_address] = true
40
+ end
41
+ end
42
+
43
+ property :type, default: :default
44
+ property :match_type?, body: ->(register) { register.type == type }
45
+ property :writable?, initial: -> { writability }
46
+ property :readable?, initial: -> { readability }
47
+ property :settings, forward_to_helper: true
48
+
49
+ build do |value|
50
+ @type = value[:type]
51
+ @options = value[:options]
52
+ helper.need_bit_fields? || register.need_no_children
53
+ end
54
+
55
+ verify(:component) do
56
+ error_condition do
57
+ helper.need_bit_fields? && register.bit_fields.empty?
58
+ end
59
+ message { 'no bit fields are given' }
60
+ end
61
+
62
+ private
63
+
64
+ attr_reader :options
65
+
66
+ def writability
67
+ instance_exec(&(helper.writability || default_writability))
68
+ end
69
+
70
+ def default_writability
71
+ -> { register.bit_fields.any?(&:writable?) }
72
+ end
73
+
74
+ def readability
75
+ instance_exec(&(helper.readability || default_readability))
76
+ end
77
+
78
+ def default_readability
79
+ lambda do
80
+ block = ->(bit_field) { bit_field.readable? || bit_field.reserved? }
81
+ register.bit_fields.any?(&block)
82
+ end
83
+ end
84
+ end
85
+
86
+ default_feature do
87
+ support_array_register
88
+
89
+ verify(:feature) do
90
+ error_condition { @type }
91
+ message { "unknown register type: #{@type.inspect}" }
92
+ end
93
+ end
94
+
95
+ factory do
96
+ convert_value do |value|
97
+ type, options = split_input_value(value)
98
+ { type: find_type(type), options: Array(options) }
99
+ end
100
+
101
+ def select_feature(cell)
102
+ if cell.empty_value?
103
+ target_feature
104
+ else
105
+ target_features[cell.value[:type]]
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def split_input_value(value)
112
+ if value.is_a?(String)
113
+ split_string_value(value)
114
+ else
115
+ input_value = Array(value)
116
+ [input_value[0], input_value[1..-1]]
117
+ end
118
+ end
119
+
120
+ def split_string_value(value)
121
+ type, options = split_string(value, ':', 2)
122
+ [type, split_string(options, /[,\n]/, 0)]
123
+ end
124
+
125
+ def split_string(value, separator, limit)
126
+ value&.split(separator, limit)&.map(&:strip)
127
+ end
128
+
129
+ def find_type(type)
130
+ types = target_features.keys
131
+ types.find(&type.to_sym.method(:casecmp?)) || type
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :external) do
4
+ register_map do
5
+ writable? { true }
6
+ readable? { true }
7
+ no_bit_fields
8
+
9
+ verify(:component) do
10
+ error_condition { register.size && register.size.length > 1 }
11
+ message do
12
+ 'external register type supports single size definition only'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :indirect) do
4
+ register_map do
5
+ define_helpers do
6
+ index_verifier = Class.new do
7
+ def initialize(&block)
8
+ instance_eval(&block)
9
+ end
10
+
11
+ def error_condition(&block)
12
+ @error_condition = block
13
+ end
14
+
15
+ def message(&block)
16
+ @message = block
17
+ end
18
+
19
+ def verify(feature, index)
20
+ error?(feature, index) && raise_error(feature, index)
21
+ end
22
+
23
+ def error?(feature, index)
24
+ feature.instance_exec(index, &@error_condition)
25
+ end
26
+
27
+ def raise_error(feature, index)
28
+ error_message = feature.instance_exec(index, &@message)
29
+ feature.__send__(:error, error_message)
30
+ end
31
+ end
32
+
33
+ define_method(:verify_index) do |&block|
34
+ index_verifiers << index_verifier.new(&block)
35
+ end
36
+
37
+ def index_verifiers
38
+ @index_verifiers ||= []
39
+ end
40
+ end
41
+
42
+ define_struct :index_entry, [:name, :value] do
43
+ def value_index?
44
+ !array_index?
45
+ end
46
+
47
+ def array_index?
48
+ value.nil?
49
+ end
50
+
51
+ def distinguishable?(other)
52
+ name == other.name && value != other.value &&
53
+ [self, other].all?(&:value_index?)
54
+ end
55
+
56
+ def find_index_field(bit_fields)
57
+ bit_fields.find { |bit_field| bit_field.full_name == name }
58
+ end
59
+ end
60
+
61
+ property :index_entries
62
+ property :collect_index_fields do |bit_fields|
63
+ index_entries.map { |entry| entry.find_index_field(bit_fields) }
64
+ end
65
+
66
+ byte_size { byte_width }
67
+ support_array_register
68
+ support_overlapped_address
69
+
70
+ input_pattern [
71
+ /(#{variable_name}\.#{variable_name})/,
72
+ /(#{variable_name}\.#{variable_name}):(#{integer})?/,
73
+ /(#{variable_name})/,
74
+ /(#{variable_name}):(#{integer})?/
75
+ ], match_automatically: false
76
+
77
+ build do
78
+ @index_entries = parse_index_entries
79
+ end
80
+
81
+ verify(:component) do
82
+ error_condition do
83
+ register.array? &&
84
+ register.array_size.length < array_index_fields.length
85
+ end
86
+ message { 'too many array indices are given' }
87
+ end
88
+
89
+ verify(:component) do
90
+ error_condition do
91
+ register.array? &&
92
+ register.array_size.length > array_index_fields.length
93
+ end
94
+ message { 'less array indices are given' }
95
+ end
96
+
97
+ verify(:all) do
98
+ check_error do
99
+ index_entries.each(&method(:verify_indirect_index))
100
+ end
101
+ end
102
+
103
+ verify_index do
104
+ error_condition do |index|
105
+ !index_entries.one? { |other| other.name == index.name }
106
+ end
107
+ message do |index|
108
+ "same bit field is used as indirect index more than once: #{index.name}"
109
+ end
110
+ end
111
+
112
+ verify_index do
113
+ error_condition { |index| !index_field(index) }
114
+ message do |index|
115
+ "no such bit field for indirect index is found: #{index.name}"
116
+ end
117
+ end
118
+
119
+ verify_index do
120
+ error_condition do |index|
121
+ index_field(index).register.name == register.name
122
+ end
123
+ message do |index|
124
+ "own bit field is not allowed for indirect index: #{index.name}"
125
+ end
126
+ end
127
+
128
+ verify_index do
129
+ error_condition { |index| index_field(index).register.array? }
130
+ message do |index|
131
+ 'bit field of array register is not allowed ' \
132
+ "for indirect index: #{index.name}"
133
+ end
134
+ end
135
+
136
+ verify_index do
137
+ error_condition { |index| index_field(index).sequential? }
138
+ message do |index|
139
+ 'sequential bit field is not allowed ' \
140
+ "for indirect index: #{index.name}"
141
+ end
142
+ end
143
+
144
+ verify_index do
145
+ error_condition { |index| index_field(index).reserved? }
146
+ message do |index|
147
+ 'reserved bit field is not allowed ' \
148
+ "for indirect index: #{index.name}"
149
+ end
150
+ end
151
+
152
+ verify_index do
153
+ error_condition do |index|
154
+ !index.array_index? &&
155
+ (index.value > (2**index_field(index).width - 1))
156
+ end
157
+ message do |index|
158
+ 'bit width of indirect index is not enough for ' \
159
+ "index value #{index.value}: #{index.name}"
160
+ end
161
+ end
162
+
163
+ verify_index do
164
+ error_condition do |index|
165
+ index.array_index? &&
166
+ (array_index_value(index) > 2**index_field(index).width)
167
+ end
168
+ message do |index|
169
+ 'bit width of indirect index is not enough for ' \
170
+ "array size #{array_index_value(index)}: #{index.name}"
171
+ end
172
+ end
173
+
174
+ verify(:all) do
175
+ error_condition { !distinguishable? }
176
+ message { 'cannot be distinguished from other registers' }
177
+ end
178
+
179
+ private
180
+
181
+ def parse_index_entries
182
+ (!options.empty? && options.map(&method(:create_index_entry))) ||
183
+ (error 'no indirect indices are given')
184
+ end
185
+
186
+ def create_index_entry(value)
187
+ input_values = split_value(value)
188
+ if input_values.size == 2
189
+ index_entry.new(input_values[0], convert_index_value(input_values[1]))
190
+ elsif input_values.size == 1
191
+ index_entry.new(input_values[0])
192
+ else
193
+ error 'too many arguments for indirect index ' \
194
+ "are given: #{value.inspect}"
195
+ end
196
+ end
197
+
198
+ def split_value(value)
199
+ input_value = Array(value)
200
+ field_name = input_value.first
201
+ if sting_or_symbol?(field_name) && match_pattern(field_name)
202
+ [*match_data.captures, *input_value[1..-1]]
203
+ else
204
+ error "illegal input value for indirect index: #{value.inspect}"
205
+ end
206
+ end
207
+
208
+ def sting_or_symbol?(value)
209
+ [String, Symbol].any?(&value.method(:is_a?))
210
+ end
211
+
212
+ def convert_index_value(value)
213
+ Integer(value)
214
+ rescue ArgumentError, TypeError
215
+ error "cannot convert #{value.inspect} into indirect index value"
216
+ end
217
+
218
+ def verify_indirect_index(index)
219
+ helper.index_verifiers.each { |verifier| verifier.verify(self, index) }
220
+ end
221
+
222
+ def index_field(index)
223
+ @index_fields ||= {}
224
+ @index_fields[index.name] ||=
225
+ index.find_index_field(register_block.bit_fields)
226
+ end
227
+
228
+ def array_index_fields
229
+ @array_index_fields ||= index_entries.select(&:array_index?)
230
+ end
231
+
232
+ def array_index_value(index)
233
+ @array_index_values ||=
234
+ array_index_fields
235
+ .map.with_index { |entry, i| [entry.name, register.array_size[i]] }
236
+ .to_h
237
+ @array_index_values[index.name]
238
+ end
239
+
240
+ def distinguishable?
241
+ register_block
242
+ .registers.select { |other| share_same_range?(other) }
243
+ .all? { |other| distinguishable_indices?(other.index_entries) }
244
+ end
245
+
246
+ def share_same_range?(other)
247
+ register.name != other.name && register.overlap?(other)
248
+ end
249
+
250
+ def distinguishable_indices?(other_entries)
251
+ index_entries.any? do |entry|
252
+ other_entries.any?(&entry.method(:distinguishable?))
253
+ end
254
+ end
255
+ end
256
+ end