rggen-default-register-map 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe8b1e59902fdb073ec6dea91243a8097438b70d778577965447cc6e4bf15de9
4
- data.tar.gz: 6b1a73e099e9ae2be4bc3fe969698596a89d88016f2b9c1d79a2729167486dbd
3
+ metadata.gz: 1b0bae9efe6712231b3219daa71f3941af91a4c2249ec645c60a30e287e4eb7f
4
+ data.tar.gz: 0af85b7cb0d5bd5d84aef39efbbce6d6d547c8b5ef4f10d9f1dd346a3a7916fd
5
5
  SHA512:
6
- metadata.gz: 83341847964c9b5e03d608489f193b13b52df6d5a59fdbc7eff557d5fd4976fa804e7d14883029268de05eb7579d8081686a5fc061f08c94d671d3739cd8ca7d
7
- data.tar.gz: 3dfbb098f07a0f4fb0d6f9a61fe4fcc08e36f96f8eea63395ab82a3f5b358b240c70dad3073f64fcc1bffd25b96eba3f33ef233697c294115044f402ea75cf32
6
+ metadata.gz: dc201ab3794f9be0370ab5e5ac6553ff468f6f32dc012364f0a99c82ccd07cda27789ea66e53031b24f199a60a0dfc06c3d82dbc3f828168c4cae862a86b0db5
7
+ data.tar.gz: d7a5c1ef1abdcfc2941b513291ce9ff8d7be34958534b850fe95eabc13f5e10b1bf3dfb7047e9652e65fd02ab2aa7e31b8530557a3ac8b95c3d1daf37bcd5b27
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![Gitter](https://badges.gitter.im/rggen/rggen.svg)](https://gitter.im/rggen/rggen?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
7
7
 
8
8
 
9
- # Rggen::DefaultRegisterMap
9
+ # RgGen::DefaultRegisterMap
10
10
 
11
11
  RgGen::DefaultRegisterMap provides following features.
12
12
 
@@ -33,7 +33,10 @@ module RgGen
33
33
  'default_register_map/register/type/external',
34
34
  'default_register_map/register/type/indirect',
35
35
  'default_register_map/register_block/byte_size',
36
- 'default_register_map/register_block/name'
36
+ 'default_register_map/register_block/name',
37
+ 'default_register_map/register_file/name',
38
+ 'default_register_map/register_file/offset_address',
39
+ 'default_register_map/register_file/size'
37
40
  ].freeze
38
41
 
39
42
  def self.load_features
@@ -100,7 +100,7 @@ RgGen.define_simple_feature(:bit_field, :bit_assignment) do
100
100
 
101
101
  def previous_bit_field
102
102
  index = bit_field.component_index - 1
103
- register.bit_fields[index]
103
+ bit_fields[index]
104
104
  end
105
105
 
106
106
  def calc_next_lsb(bit_field)
@@ -138,9 +138,7 @@ RgGen.define_simple_feature(:bit_field, :bit_assignment) do
138
138
  end
139
139
 
140
140
  def overlap?
141
- register
142
- .bit_fields
143
- .any? { |bit_field| (bit_field.bit_map & bit_map).nonzero? }
141
+ bit_fields.any? { |bit_field| (bit_field.bit_map & bit_map).nonzero? }
144
142
  end
145
143
  end
146
144
  end
@@ -2,19 +2,15 @@
2
2
 
3
3
  RgGen.define_simple_feature(:bit_field, :name) do
4
4
  register_map do
5
- property :name, initial: -> { register.name }
5
+ property :name, default: -> { register.name }
6
6
  property :full_name, forward_to: :get_full_name
7
7
 
8
8
  input_pattern variable_name
9
9
 
10
10
  build do |value|
11
- @name =
12
- if pattern_matched?
13
- match_data.to_s
14
- else
15
- error "illegal input value for bit field name: #{value.inspect}"
16
- end
17
- @full_name = [register.name, @name]
11
+ pattern_matched? ||
12
+ (error "illegal input value for bit field name: #{value.inspect}")
13
+ @name = match_data.to_s
18
14
  end
19
15
 
20
16
  verify(:feature) do
@@ -22,16 +18,19 @@ RgGen.define_simple_feature(:bit_field, :name) do
22
18
  message { "duplicated bit field name: #{name}" }
23
19
  end
24
20
 
25
- printable :name
21
+ printable(:name) do
22
+ RgGen::Core::Utility::CodeUtility
23
+ .array_name(name, Array(bit_field.sequence_size))
24
+ end
26
25
 
27
26
  private
28
27
 
29
28
  def get_full_name(separator = '.')
30
- @full_name&.join(separator) || register.name
29
+ [register.full_name(separator), *@name].join(separator)
31
30
  end
32
31
 
33
32
  def duplicated_name?
34
- register.bit_fields.any? { |bit_field| bit_field.name == name }
33
+ bit_fields.any? { |bit_field| bit_field.name == name }
35
34
  end
36
35
  end
37
36
  end
@@ -7,18 +7,12 @@ RgGen.define_simple_feature(:bit_field, :reference) do
7
7
  property :reference_width, forward_to: :required_width
8
8
  property :find_reference, forward_to: :find_reference_bit_field
9
9
 
10
- input_pattern [
11
- /(#{variable_name})\.(#{variable_name})/,
12
- /(#{variable_name})/
13
- ]
10
+ input_pattern /(#{variable_name}(?:\.#{variable_name})*)/
14
11
 
15
12
  build do |value|
16
- @input_reference =
17
- if pattern_matched?
18
- match_data[1..2].compact.join('.')
19
- else
20
- error "illegal input value for reference: #{value.inspect}"
21
- end
13
+ pattern_matched? ||
14
+ (error "illegal input value for reference: #{value.inspect}")
15
+ @input_reference = match_data.to_s
22
16
  end
23
17
 
24
18
  verify(:component) do
@@ -38,20 +32,46 @@ RgGen.define_simple_feature(:bit_field, :reference) do
38
32
 
39
33
  verify(:all) do
40
34
  error_condition do
41
- reference? && !register.array? && reference_bit_field.register.array?
35
+ reference? && within_array?(reference_bit_field) &&
36
+ (bit_field.depth != reference_bit_field.depth)
42
37
  end
43
38
  message do
44
- 'bit field of array register is not allowed for ' \
45
- "reference bit field: #{@input_reference}"
39
+ 'depth of layer is not matched: ' \
40
+ "own #{bit_field.depth} " \
41
+ "reference #{reference_bit_field.depth}"
42
+ end
43
+ end
44
+
45
+ define_helpers do
46
+ def verify_array(&block)
47
+ array_verifiers << create_verifier(&block)
48
+ end
49
+
50
+ def array_verifiers
51
+ @array_verifiers ||= []
46
52
  end
47
53
  end
48
54
 
49
55
  verify(:all) do
50
- error_condition { reference? && !match_array_size? }
51
- message do
56
+ check_error do
57
+ reference? && within_array?(reference_bit_field) &&
58
+ helper.array_verifiers.each(&method(:verify_array))
59
+ end
60
+ end
61
+
62
+ verify_array do
63
+ error_condition { |own, ref| !own.array? && ref.array? }
64
+ message do |*_, layer|
65
+ "bit field within array #{layer.to_s.tr('_', ' ')} is not allowed for " \
66
+ "reference bit field: #{@input_reference}"
67
+ end
68
+ end
69
+
70
+ verify_array do
71
+ error_condition { |own, ref| unmatch_array_size?(own, ref) }
72
+ message do |own, ref|
52
73
  'array size is not matched: ' \
53
- "own #{register.array_size} " \
54
- "reference #{reference_bit_field.register.array_size}"
74
+ "own #{own.array_size} reference #{ref.array_size}"
55
75
  end
56
76
  end
57
77
 
@@ -66,7 +86,7 @@ RgGen.define_simple_feature(:bit_field, :reference) do
66
86
  end
67
87
 
68
88
  verify(:all) do
69
- error_condition { reference? && !match_sequence_size? }
89
+ error_condition { reference? && unmatch_sequence_size? }
70
90
  message do
71
91
  'sequence size is not matched: ' \
72
92
  "own #{bit_field.sequence_size} " \
@@ -125,14 +145,23 @@ RgGen.define_simple_feature(:bit_field, :reference) do
125
145
  find_reference_bit_field(register_block.bit_fields)
126
146
  end
127
147
 
128
- def match_array_size?
129
- !(register.array? && reference_bit_field.register.array?) ||
130
- register.array_size == reference_bit_field.register.array_size
148
+ def within_array?(bit_field)
149
+ bit_field.register_files.any?(&:array?) || bit_field.register.array?
150
+ end
151
+
152
+ def verify_array(verifier)
153
+ [*register_files, register]
154
+ .zip([*reference_bit_field.register_files, reference_bit_field.register])
155
+ .each { |own, ref| verifier.verify(self, own, ref, own.layer) }
156
+ end
157
+
158
+ def unmatch_array_size?(own, ref)
159
+ own.array? && ref.array? && own.array_size != ref.array_size
131
160
  end
132
161
 
133
- def match_sequence_size?
134
- !(bit_field.sequential? && reference_bit_field.sequential?) ||
135
- bit_field.sequence_size == reference_bit_field.sequence_size
162
+ def unmatch_sequence_size?
163
+ bit_field.sequential? && reference_bit_field.sequential? &&
164
+ (bit_field.sequence_size != reference_bit_field.sequence_size)
136
165
  end
137
166
 
138
167
  def required_width
@@ -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
@@ -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
@@ -3,6 +3,7 @@
3
3
  RgGen.define_simple_feature(:register, :offset_address) do
4
4
  register_map do
5
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
 
@@ -29,7 +30,10 @@ RgGen.define_simple_feature(:register, :offset_address) do
29
30
  end
30
31
 
31
32
  verify(:component) do
32
- 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
33
37
  message do
34
38
  'offset address range exceeds byte size of register block' \
35
39
  "(#{register_block.byte_size}): " \
@@ -39,32 +43,49 @@ RgGen.define_simple_feature(:register, :offset_address) do
39
43
 
40
44
  verify(:component) do
41
45
  error_condition do
42
- register_block.registers.any? do |register|
43
- overlap_address_range?(register) &&
44
- support_unique_range_only?(register)
46
+ files_and_registers.any? do |other|
47
+ overlap_address_range?(other) && exclusive_range?(other)
45
48
  end
46
49
  end
47
50
  message do
48
51
  'offset address range overlaps with other offset address range: ' \
49
- "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)}"
50
53
  end
51
54
  end
52
55
 
53
56
  printable(:offset_address) do
54
- [start_address, end_address]
55
- .map(&method(:printable_address)).join(' - ')
57
+ expand_addresses.map(&method(:format_address))
56
58
  end
57
59
 
58
60
  private
59
61
 
60
62
  def default_offset_address
61
63
  register.component_index.zero? && 0 ||
62
- (previous_register.offset_address + previous_register.byte_size)
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
63
73
  end
64
74
 
65
- def previous_register
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
66
87
  index = register.component_index - 1
67
- register_block.registers[index]
88
+ files_and_registers[index]
68
89
  end
69
90
 
70
91
  def bus_width
@@ -75,35 +96,30 @@ RgGen.define_simple_feature(:register, :offset_address) do
75
96
  configuration.byte_width
76
97
  end
77
98
 
78
- def start_address
79
- offset_address
80
- end
81
-
82
- def end_address
83
- start_address + register.byte_size - 1
99
+ def overlap_address_range?(other)
100
+ overlap_range?(other) && competitive_access?(other)
84
101
  end
85
102
 
86
- def overlap_address_range?(other_register)
87
- 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)
88
107
  end
89
108
 
90
- def overlap_range?(other_register)
91
- own = address_range
92
- other = other_register.address_range
93
- 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) }
94
112
  end
95
113
 
96
- def match_access?(other_register)
97
- (register.writable? && other_register.writable?) ||
98
- (register.readable? && other_register.readable?)
114
+ def exclusive_range?(other)
115
+ other.register_file? || !(shared_address? && register.match_type?(other))
99
116
  end
100
117
 
101
- def support_unique_range_only?(other_register)
102
- !(register.settings[:support_overlapped_address] &&
103
- register.match_type?(other_register))
118
+ def shared_address?
119
+ register.settings[:support_shared_address]
104
120
  end
105
121
 
106
- def printable_address(address)
122
+ def format_address(address)
107
123
  print_width = (register_block.local_address_width + 3) / 4
108
124
  format('0x%0*x', print_width, address)
109
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
@@ -40,21 +40,25 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
40
40
  index_entries.map { |entry| entry.find_index_field(bit_fields) }
41
41
  end
42
42
 
43
- byte_size { byte_width }
43
+ support_shared_address
44
44
  support_array_register
45
- support_overlapped_address
46
45
 
47
46
  input_pattern [
48
- /(#{variable_name}\.#{variable_name})/,
49
- /(#{variable_name}\.#{variable_name}):(#{integer})?/,
50
- /(#{variable_name})/,
51
- /(#{variable_name}):(#{integer})?/
47
+ /(#{variable_name}(?:\.#{variable_name})*)/,
48
+ /(#{variable_name}(?:\.#{variable_name})*):(#{integer})/
52
49
  ], match_automatically: false
53
50
 
54
51
  build do
55
52
  @index_entries = parse_index_entries
56
53
  end
57
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
+
58
62
  verify(:component) do
59
63
  error_condition do
60
64
  register.array? &&
@@ -95,17 +99,27 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
95
99
 
96
100
  verify_index do
97
101
  error_condition do |index|
98
- index_field(index).register.name == register.name
102
+ index_field(index).register.full_name == register.full_name
99
103
  end
100
104
  message do |index|
101
105
  "own bit field is not allowed for indirect index: #{index.name}"
102
106
  end
103
107
  end
104
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
+
105
119
  verify_index do
106
120
  error_condition { |index| index_field(index).register.array? }
107
121
  message do |index|
108
- 'bit field of array register is not allowed ' \
122
+ 'bit field within array register is not allowed ' \
109
123
  "for indirect index: #{index.name}"
110
124
  end
111
125
  end
@@ -219,8 +233,8 @@ RgGen.define_list_item_feature(:register, :type, :indirect) do
219
233
  end
220
234
 
221
235
  def distinguishable?
222
- register_block
223
- .registers.select { |other| share_same_range?(other) }
236
+ files_and_registers
237
+ .select { |other| other.register? && share_same_range?(other) }
224
238
  .all? { |other| distinguishable_indices?(other.index_entries) }
225
239
  end
226
240
 
@@ -7,12 +7,9 @@ RgGen.define_simple_feature(:register_block, :name) do
7
7
  input_pattern variable_name
8
8
 
9
9
  build do |value|
10
- @name =
11
- if pattern_matched?
12
- match_data.to_s
13
- else
14
- error "illegal input value for register block name: #{value.inspect}"
15
- end
10
+ pattern_matched? ||
11
+ (error "illegal input value for register block name: #{value.inspect}")
12
+ @name = match_data.to_s
16
13
  end
17
14
 
18
15
  verify(:feature) do
@@ -30,9 +27,7 @@ RgGen.define_simple_feature(:register_block, :name) do
30
27
  private
31
28
 
32
29
  def duplicated_name?
33
- register_map
34
- .register_blocks
35
- .any? { |register_block| register_block.name == name }
30
+ register_blocks.any? { |register_block| register_block.name == name }
36
31
  end
37
32
  end
38
33
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_file, :name) do
4
+ register_map do
5
+ property :name
6
+ property :full_name, forward_to: :get_full_name
7
+
8
+ input_pattern variable_name
9
+
10
+ build do |value|
11
+ pattern_matched? ||
12
+ (error "illegal input value for register file name: #{value.inspect}")
13
+ @name = match_data.to_s
14
+ end
15
+
16
+ verify(:feature) do
17
+ error_condition { !name }
18
+ message { 'no register file name is given' }
19
+ end
20
+
21
+ verify(:feature) do
22
+ error_condition { duplicated_name? }
23
+ message { "duplicated register file name: #{name}" }
24
+ end
25
+
26
+ printable(:name) do
27
+ array_name
28
+ end
29
+
30
+ printable(:layer_name) do
31
+ [
32
+ register_file(:upper)&.printables&.fetch(:layer_name),
33
+ array_name
34
+ ].compact.join('.')
35
+ end
36
+
37
+ private
38
+
39
+ def get_full_name(separator = '.')
40
+ [*register_file(:upper)&.full_name(separator), name].join(separator)
41
+ end
42
+
43
+ def duplicated_name?
44
+ files_and_registers
45
+ .any? { |file_or_register| file_or_register.name == name }
46
+ end
47
+
48
+ def array_name
49
+ RgGen::Core::Utility::CodeUtility
50
+ .array_name(name, register_file.array_size)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_file, :offset_address) do
4
+ register_map do
5
+ property :offset_address, initial: -> { defalt_offset_address }
6
+ property :expanded_offset_addresses, forward_to: :expand_addresses
7
+ property :address_range, initial: -> { start_address..end_address }
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.negative? }
20
+ message { "offset address is less than 0: #{offset_address}" }
21
+ end
22
+
23
+ verify(:feature) do
24
+ error_condition { (offset_address % byte_width).nonzero? }
25
+ message do
26
+ "offset address is not aligned with bus width(#{bus_width}): " \
27
+ "0x#{offset_address.to_s(16)}"
28
+ end
29
+ end
30
+
31
+ verify(:component) do
32
+ error_condition do
33
+ register_file.parent.register_block? &&
34
+ end_address > register_block.byte_size
35
+ end
36
+ message do
37
+ 'offset address range exceeds byte size of register block' \
38
+ "(#{register_block.byte_size}): " \
39
+ "0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
40
+ end
41
+ end
42
+
43
+ verify(:component) do
44
+ error_condition do
45
+ files_and_registers.any?(&method(:overlap_address_range?))
46
+ end
47
+ message do
48
+ 'offset address range overlaps with other offset address range: ' \
49
+ "0x#{start_address(true).to_s(16)}-0x#{end_address(true).to_s(16)}"
50
+ end
51
+ end
52
+
53
+ printable(:offset_address) do
54
+ expand_addresses.map(&method(:format_address))
55
+ end
56
+
57
+ private
58
+
59
+ def defalt_offset_address
60
+ register_file.component_index.zero? && 0 ||
61
+ (previous_component.offset_address + previous_component.byte_size)
62
+ end
63
+
64
+ def previous_component
65
+ index = register_file.component_index - 1
66
+ block_or_file.files_and_registers[index]
67
+ end
68
+
69
+ def start_address(full = false)
70
+ full && expand_addresses.first || offset_address
71
+ end
72
+
73
+ def end_address(full = false)
74
+ start_address(full) + register_file.byte_size - 1
75
+ end
76
+
77
+ def expand_addresses
78
+ uppser_addresses = register_file(:upper)&.expanded_offset_addresses || [0]
79
+ uppser_addresses.product(expand_local_addresses).map(&:sum)
80
+ end
81
+
82
+ def expand_local_addresses
83
+ Array.new(register_file.array_size&.inject(:*) || 1) do |i|
84
+ offset_address + register_file.byte_size(false) * i
85
+ end
86
+ end
87
+
88
+ def overlap_address_range?(other)
89
+ self_range = address_range
90
+ other_range = other.address_range
91
+ self_range.include?(other_range.first) || other_range.include?(self_range.first)
92
+ end
93
+
94
+ def bus_width
95
+ configuration.bus_width
96
+ end
97
+
98
+ def byte_width
99
+ configuration.byte_width
100
+ end
101
+
102
+ def format_address(address)
103
+ print_width = (register_block.local_address_width.to_f / 4.0).ceil
104
+ format('0x%0*x', print_width, address)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_file, :size) do
4
+ register_map do
5
+ property :size
6
+ property :byte_size, forward_to: :calc_byte_size
7
+ property :array?, body: -> { !@size.nil? }
8
+ property :array_size, forward_to: :size
9
+ property :count, forward_to: :calc_count
10
+
11
+ input_pattern [
12
+ /(#{integer}(:?,#{integer})*)/,
13
+ /\[(#{integer}(:?,#{integer})*)\]/
14
+ ], match_automatically: false
15
+
16
+ build do |values|
17
+ @size =
18
+ (values.is_a?(String) && parse_string_value(values) || Array(values))
19
+ .map(&method(:convert_value))
20
+ end
21
+
22
+ verify(:feature) do
23
+ error_condition { array? && !size.all?(&:positive?) }
24
+ message do
25
+ "non positive value(s) are not allowed for register file size: #{size}"
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parse_string_value(value)
32
+ match_pattern(value) && match_data.captures.first.split(',') ||
33
+ (error "illegal input value for register file size: #{value.inspect}")
34
+ end
35
+
36
+ def convert_value(value)
37
+ Integer(value)
38
+ rescue ArgumentError, TypeError
39
+ error "cannot convert #{value.inspect} into register file size"
40
+ end
41
+
42
+ def calc_byte_size(whole_size = true)
43
+ (whole_size ? total_entries : 1) * entry_byte_size
44
+ end
45
+
46
+ def entry_byte_size
47
+ register_file.files_and_registers
48
+ .map { |r| r.offset_address + r.byte_size }.max
49
+ end
50
+
51
+ def calc_count(whole_count = true)
52
+ (whole_count ? total_entries : 1) *
53
+ register_file.files_and_registers.sum(&:count)
54
+ end
55
+
56
+ def total_entries
57
+ size&.inject(:*) || 1
58
+ end
59
+ end
60
+ end
@@ -5,6 +5,7 @@ require 'rggen/default_register_map'
5
5
  RgGen.setup :'rggen-defualt-register-map', RgGen::DefaultRegisterMap do |builder|
6
6
  builder.enable :global, [:bus_width, :address_width]
7
7
  builder.enable :register_block, [:name, :byte_size]
8
+ builder.enable :register_file, [:name, :offset_address, :size]
8
9
  builder.enable :register, [:name, :offset_address, :size, :type]
9
10
  builder.enable :register, :type, [:external, :indirect]
10
11
  builder.enable :bit_field, [
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RgGen
4
4
  module DefaultRegisterMap
5
- VERSION = '0.19.0'
5
+ VERSION = '0.20.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rggen-default-register-map
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taichi Ishitani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-17 00:00:00.000000000 Z
11
+ date: 2020-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,6 +64,9 @@ files:
64
64
  - lib/rggen/default_register_map/register/type/indirect.rb
65
65
  - lib/rggen/default_register_map/register_block/byte_size.rb
66
66
  - lib/rggen/default_register_map/register_block/name.rb
67
+ - lib/rggen/default_register_map/register_file/name.rb
68
+ - lib/rggen/default_register_map/register_file/offset_address.rb
69
+ - lib/rggen/default_register_map/register_file/size.rb
67
70
  - lib/rggen/default_register_map/setup.rb
68
71
  - lib/rggen/default_register_map/version.rb
69
72
  homepage: https://github.com/rggen/rggen-default-register-map
@@ -92,5 +95,5 @@ requirements: []
92
95
  rubygems_version: 3.1.2
93
96
  signing_key:
94
97
  specification_version: 4
95
- summary: rggen-default-register-map-0.19.0
98
+ summary: rggen-default-register-map-0.20.0
96
99
  test_files: []