rggen-default-register-map 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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