rggen-default-register-map 0.16.0 → 0.21.0

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