rggen-default-register-map 0.16.0 → 0.21.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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +3 -3
  4. data/lib/rggen/default_register_map.rb +7 -4
  5. data/lib/rggen/default_register_map/bit_field/bit_assignment.rb +32 -10
  6. data/lib/rggen/default_register_map/bit_field/initial_value.rb +144 -26
  7. data/lib/rggen/default_register_map/bit_field/name.rb +10 -11
  8. data/lib/rggen/default_register_map/bit_field/reference.rb +53 -24
  9. data/lib/rggen/default_register_map/bit_field/type/{rw.rb → rw_w1.rb} +1 -1
  10. data/lib/rggen/default_register_map/bit_field/type/rwe_rwl.rb +17 -0
  11. data/lib/rggen/default_register_map/bit_field/type/{wo.rb → wo_wo1.rb} +1 -1
  12. data/lib/rggen/default_register_map/common/comment.rb +18 -0
  13. data/lib/rggen/default_register_map/register/name.rb +23 -8
  14. data/lib/rggen/default_register_map/register/offset_address.rb +53 -32
  15. data/lib/rggen/default_register_map/register/size.rb +7 -11
  16. data/lib/rggen/default_register_map/register/type.rb +2 -6
  17. data/lib/rggen/default_register_map/register/type/external.rb +11 -0
  18. data/lib/rggen/default_register_map/register/type/indirect.rb +27 -40
  19. data/lib/rggen/default_register_map/register_block/name.rb +4 -9
  20. data/lib/rggen/default_register_map/register_file/name.rb +53 -0
  21. data/lib/rggen/default_register_map/register_file/offset_address.rb +107 -0
  22. data/lib/rggen/default_register_map/register_file/size.rb +60 -0
  23. data/lib/rggen/default_register_map/setup.rb +10 -3
  24. data/lib/rggen/default_register_map/version.rb +1 -1
  25. metadata +11 -8
  26. data/lib/rggen/default_register_map/bit_field/comment.rb +0 -18
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RgGen.define_list_item_feature(:bit_field, :type, :rw) do
3
+ RgGen.define_list_item_feature(:bit_field, :type, [:rw, :w1]) do
4
4
  register_map do
5
5
  read_write
6
6
  non_volatile
@@ -6,5 +6,22 @@ RgGen.define_list_item_feature(:bit_field, :type, [:rwe, :rwl]) do
6
6
  volatile? { !bit_field.reference? }
7
7
  initial_value require: true
8
8
  reference use: true, width: 1
9
+
10
+ verify(:all) do
11
+ error_condition do
12
+ bit_field.reference? &&
13
+ register.full_name == reference_register.full_name
14
+ end
15
+ message do
16
+ 'bit field within the same register is not allowed for ' \
17
+ "reference bit field: #{bit_field.reference.full_name}"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def reference_register
24
+ bit_field.reference.register
25
+ end
9
26
  end
10
27
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RgGen.define_list_item_feature(:bit_field, :type, :wo) do
3
+ RgGen.define_list_item_feature(:bit_field, :type, [:wo, :wo1]) do
4
4
  register_map do
5
5
  write_only
6
6
  non_volatile
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ [:register_block, :register_file, :register, :bit_field].each do |layer|
4
+ RgGen.define_simple_feature(layer, :comment) do
5
+ register_map do
6
+ property :comment, initial: -> { '' }
7
+
8
+ build do |value|
9
+ @comment =
10
+ (value.is_a?(Array) && value.join("\n") || value.to_s).chomp
11
+ end
12
+
13
+ printable :comment do
14
+ comment.empty? ? nil : comment
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,16 +3,14 @@
3
3
  RgGen.define_simple_feature(:register, :name) do
4
4
  register_map do
5
5
  property :name
6
+ property :full_name, forward_to: :get_full_name
6
7
 
7
8
  input_pattern variable_name
8
9
 
9
10
  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
11
+ pattern_matched? ||
12
+ (error "illegal input value for register name: #{value.inspect}")
13
+ @name = match_data.to_s
16
14
  end
17
15
 
18
16
  verify(:feature) do
@@ -25,12 +23,29 @@ RgGen.define_simple_feature(:register, :name) do
25
23
  message { "duplicated register name: #{name}" }
26
24
  end
27
25
 
28
- printable :name
26
+ printable(:name) do
27
+ array_name
28
+ end
29
+
30
+ printable(:layer_name) do
31
+ [register_file&.printables&.fetch(:layer_name), array_name]
32
+ .compact.join('.')
33
+ end
29
34
 
30
35
  private
31
36
 
37
+ def get_full_name(separator = '.')
38
+ [*register_file&.full_name(separator), name].join(separator)
39
+ end
40
+
32
41
  def duplicated_name?
33
- register_block.registers.any? { |register| register.name == name }
42
+ files_and_registers
43
+ .any? { |file_or_register| file_or_register.name == name }
44
+ end
45
+
46
+ def array_name
47
+ RgGen::Core::Utility::CodeUtility
48
+ .array_name(name, register.array_size)
34
49
  end
35
50
  end
36
51
  end
@@ -2,7 +2,8 @@
2
2
 
3
3
  RgGen.define_simple_feature(:register, :offset_address) do
4
4
  register_map do
5
- property :offset_address
5
+ property :offset_address, initial: -> { default_offset_address }
6
+ property :expanded_offset_addresses, forward_to: :expand_addresses
6
7
  property :address_range, initial: -> { start_address..end_address }
7
8
  property :overlap?, forward_to: :overlap_address_range?
8
9
 
@@ -15,11 +16,6 @@ RgGen.define_simple_feature(:register, :offset_address) do
15
16
  end
16
17
  end
17
18
 
18
- verify(:feature) do
19
- error_condition { !offset_address }
20
- message { 'no offset address is given' }
21
- end
22
-
23
19
  verify(:feature) do
24
20
  error_condition { offset_address.negative? }
25
21
  message { "offset address is less than 0: #{offset_address}" }
@@ -34,7 +30,10 @@ RgGen.define_simple_feature(:register, :offset_address) do
34
30
  end
35
31
 
36
32
  verify(:component) do
37
- error_condition { end_address > register_block.byte_size }
33
+ error_condition do
34
+ register.parent.register_block? &&
35
+ end_address > register_block.byte_size
36
+ end
38
37
  message do
39
38
  'offset address range exceeds byte size of register block' \
40
39
  "(#{register_block.byte_size}): " \
@@ -44,24 +43,51 @@ RgGen.define_simple_feature(:register, :offset_address) do
44
43
 
45
44
  verify(:component) do
46
45
  error_condition do
47
- register_block.registers.any? do |register|
48
- overlap_address_range?(register) &&
49
- support_unique_range_only?(register)
46
+ files_and_registers.any? do |other|
47
+ overlap_address_range?(other) && exclusive_range?(other)
50
48
  end
51
49
  end
52
50
  message do
53
51
  'offset address range overlaps with other offset address range: ' \
54
- "0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
52
+ "0x#{start_address(true).to_s(16)}-0x#{end_address(true).to_s(16)}"
55
53
  end
56
54
  end
57
55
 
58
56
  printable(:offset_address) do
59
- [start_address, end_address]
60
- .map(&method(:printable_address)).join(' - ')
57
+ expand_addresses.map(&method(:format_address))
61
58
  end
62
59
 
63
60
  private
64
61
 
62
+ def default_offset_address
63
+ register.component_index.zero? && 0 ||
64
+ (previous_component.offset_address + previous_component.byte_size)
65
+ end
66
+
67
+ def start_address(full = false)
68
+ full && expand_addresses.first || offset_address
69
+ end
70
+
71
+ def end_address(full = false)
72
+ start_address(full) + register.byte_size - 1
73
+ end
74
+
75
+ def expand_addresses
76
+ upper_offsets = register_file&.expanded_offset_addresses || [0]
77
+ upper_offsets.product(expand_local_addresses).map(&:sum)
78
+ end
79
+
80
+ def expand_local_addresses
81
+ Array.new(shared_address? && 1 || register.count) do |i|
82
+ offset_address + register.byte_width * i
83
+ end
84
+ end
85
+
86
+ def previous_component
87
+ index = register.component_index - 1
88
+ files_and_registers[index]
89
+ end
90
+
65
91
  def bus_width
66
92
  configuration.bus_width
67
93
  end
@@ -70,35 +96,30 @@ RgGen.define_simple_feature(:register, :offset_address) do
70
96
  configuration.byte_width
71
97
  end
72
98
 
73
- def start_address
74
- offset_address
75
- end
76
-
77
- def end_address
78
- start_address + register.byte_size - 1
99
+ def overlap_address_range?(other)
100
+ overlap_range?(other) && competitive_access?(other)
79
101
  end
80
102
 
81
- def overlap_address_range?(other_register)
82
- overlap_range?(other_register) && match_access?(other_register)
103
+ def overlap_range?(other)
104
+ self_range = address_range
105
+ othre_range = other.address_range
106
+ self_range.include?(othre_range.first) || othre_range.include?(self_range.first)
83
107
  end
84
108
 
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)
109
+ def competitive_access?(other)
110
+ other.register_file? ||
111
+ [:writable?, :readable?].any? { |access| [register, other].all?(&access) }
89
112
  end
90
113
 
91
- def match_access?(other_register)
92
- (register.writable? && other_register.writable?) ||
93
- (register.readable? && other_register.readable?)
114
+ def exclusive_range?(other)
115
+ other.register_file? || !(shared_address? && register.match_type?(other))
94
116
  end
95
117
 
96
- def support_unique_range_only?(other_register)
97
- !(register.settings[:support_overlapped_address] &&
98
- register.match_type?(other_register))
118
+ def shared_address?
119
+ register.settings[:support_shared_address]
99
120
  end
100
121
 
101
- def printable_address(address)
122
+ def format_address(address)
102
123
  print_width = (register_block.local_address_width + 3) / 4
103
124
  format('0x%0*x', print_width, address)
104
125
  end
@@ -5,10 +5,10 @@ RgGen.define_simple_feature(:register, :size) do
5
5
  property :size
6
6
  property :width, initial: -> { calc_width }
7
7
  property :byte_width, initial: -> { width / 8 }
8
- property :byte_size, initial: -> { calc_byte_size }
8
+ property :byte_size, forward_to: :calc_byte_size
9
9
  property :array?, forward_to: :array_register?
10
10
  property :array_size, forward_to: :array_registers
11
- property :count, initial: -> { calc_count }
11
+ property :count, forward_to: :calc_count
12
12
 
13
13
  input_pattern [
14
14
  /(#{integer}(:?,#{integer})*)/,
@@ -26,10 +26,6 @@ RgGen.define_simple_feature(:register, :size) do
26
26
  end
27
27
  end
28
28
 
29
- printable(:array_size) do
30
- (array_register? || nil) && "[#{array_registers.join(', ')}]"
31
- end
32
-
33
29
  private
34
30
 
35
31
  def parse_values(values)
@@ -72,9 +68,9 @@ RgGen.define_simple_feature(:register, :size) do
72
68
  .max
73
69
  end
74
70
 
75
- def calc_byte_size
76
- if register.settings[:byte_size]
77
- instance_exec(&register.settings[:byte_size])
71
+ def calc_byte_size(whole_size = true)
72
+ if !whole_size || register.settings[:support_shared_address]
73
+ byte_width
78
74
  else
79
75
  Array(@size).reduce(1, :*) * byte_width
80
76
  end
@@ -88,8 +84,8 @@ RgGen.define_simple_feature(:register, :size) do
88
84
  array_register? && @size || nil
89
85
  end
90
86
 
91
- def calc_count
92
- Array(array_registers).reduce(1, :*)
87
+ def calc_count(whole_count = true)
88
+ whole_count ? (@count ||= Array(array_registers).reduce(1, :*)) : 1
93
89
  end
94
90
  end
95
91
  end
@@ -31,12 +31,8 @@ RgGen.define_list_feature(:register, :type) do
31
31
  settings[:support_array] = true
32
32
  end
33
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
34
+ def support_shared_address
35
+ settings[:support_shared_address] = true
40
36
  end
41
37
  end
42
38
 
@@ -6,11 +6,22 @@ RgGen.define_list_item_feature(:register, :type, :external) do
6
6
  readable? { true }
7
7
  no_bit_fields
8
8
 
9
+ verify(:feature) do
10
+ error_condition { register.parent.register_file? }
11
+ message do
12
+ 'external register type is not allowed to be put within register file'
13
+ end
14
+ end
15
+
9
16
  verify(:component) do
10
17
  error_condition { register.size && register.size.length > 1 }
11
18
  message do
12
19
  'external register type supports single size definition only'
13
20
  end
14
21
  end
22
+
23
+ printable(:byte_size) do
24
+ "#{register.byte_size} bytes"
25
+ end
15
26
  end
16
27
  end
@@ -3,35 +3,8 @@
3
3
  RgGen.define_list_item_feature(:register, :type, :indirect) do
4
4
  register_map do
5
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)
6
+ def verify_index(&block)
7
+ index_verifiers << create_verifier(&block)
35
8
  end
36
9
 
37
10
  def index_verifiers
@@ -67,21 +40,25 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
67
40
  index_entries.map { |entry| entry.find_index_field(bit_fields) }
68
41
  end
69
42
 
70
- byte_size { byte_width }
43
+ support_shared_address
71
44
  support_array_register
72
- support_overlapped_address
73
45
 
74
46
  input_pattern [
75
- /(#{variable_name}\.#{variable_name})/,
76
- /(#{variable_name}\.#{variable_name}):(#{integer})?/,
77
- /(#{variable_name})/,
78
- /(#{variable_name}):(#{integer})?/
47
+ /(#{variable_name}(?:\.#{variable_name})*)/,
48
+ /(#{variable_name}(?:\.#{variable_name})*):(#{integer})/
79
49
  ], match_automatically: false
80
50
 
81
51
  build do
82
52
  @index_entries = parse_index_entries
83
53
  end
84
54
 
55
+ verify(:component) do
56
+ error_condition do
57
+ !(register.array? || array_index_fields.empty?)
58
+ end
59
+ message { 'array indices are given to non-array register' }
60
+ end
61
+
85
62
  verify(:component) do
86
63
  error_condition do
87
64
  register.array? &&
@@ -95,7 +72,7 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
95
72
  register.array? &&
96
73
  register.array_size.length > array_index_fields.length
97
74
  end
98
- message { 'less array indices are given' }
75
+ message { 'few array indices are given' }
99
76
  end
100
77
 
101
78
  verify(:all) do
@@ -122,17 +99,27 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
122
99
 
123
100
  verify_index do
124
101
  error_condition do |index|
125
- index_field(index).register.name == register.name
102
+ index_field(index).register.full_name == register.full_name
126
103
  end
127
104
  message do |index|
128
105
  "own bit field is not allowed for indirect index: #{index.name}"
129
106
  end
130
107
  end
131
108
 
109
+ verify_index do
110
+ error_condition do |index|
111
+ index_field(index).register_files.any?(&:array?)
112
+ end
113
+ message do |index|
114
+ 'bit field within array register file is not allowed ' \
115
+ "for indirect index: #{index.name}"
116
+ end
117
+ end
118
+
132
119
  verify_index do
133
120
  error_condition { |index| index_field(index).register.array? }
134
121
  message do |index|
135
- 'bit field of array register is not allowed ' \
122
+ 'bit field within array register is not allowed ' \
136
123
  "for indirect index: #{index.name}"
137
124
  end
138
125
  end
@@ -246,8 +233,8 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
246
233
  end
247
234
 
248
235
  def distinguishable?
249
- register_block
250
- .registers.select { |other| share_same_range?(other) }
236
+ files_and_registers
237
+ .select { |other| other.register? && share_same_range?(other) }
251
238
  .all? { |other| distinguishable_indices?(other.index_entries) }
252
239
  end
253
240