rggen 0.3.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 (152) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +7 -0
  3. data/.rubocop_todo.yml +91 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +31 -0
  7. data/bin/rggen +6 -0
  8. data/lib/rggen/base/component.rb +27 -0
  9. data/lib/rggen/base/component_factory.rb +46 -0
  10. data/lib/rggen/base/hierarchical_accessors.rb +87 -0
  11. data/lib/rggen/base/hierarchical_item_accessors.rb +79 -0
  12. data/lib/rggen/base/item.rb +24 -0
  13. data/lib/rggen/base/item_factory.rb +20 -0
  14. data/lib/rggen/builder/builder.rb +69 -0
  15. data/lib/rggen/builder/category.rb +52 -0
  16. data/lib/rggen/builder/component_entry.rb +50 -0
  17. data/lib/rggen/builder/component_store.rb +42 -0
  18. data/lib/rggen/builder/input_component_store.rb +25 -0
  19. data/lib/rggen/builder/item_store.rb +89 -0
  20. data/lib/rggen/builder/list_item_entry.rb +81 -0
  21. data/lib/rggen/builder/output_component_store.rb +13 -0
  22. data/lib/rggen/builder/simple_item_entry.rb +33 -0
  23. data/lib/rggen/builtins/bit_field/bit_assignment.rb +39 -0
  24. data/lib/rggen/builtins/bit_field/field_model_creation.rb +25 -0
  25. data/lib/rggen/builtins/bit_field/field_model_declaration.rb +9 -0
  26. data/lib/rggen/builtins/bit_field/initial_value.rb +36 -0
  27. data/lib/rggen/builtins/bit_field/name.rb +26 -0
  28. data/lib/rggen/builtins/bit_field/reference.rb +42 -0
  29. data/lib/rggen/builtins/bit_field/reserved.rb +9 -0
  30. data/lib/rggen/builtins/bit_field/ro.rb +19 -0
  31. data/lib/rggen/builtins/bit_field/rw.erb +13 -0
  32. data/lib/rggen/builtins/bit_field/rw.rb +25 -0
  33. data/lib/rggen/builtins/bit_field/type.rb +205 -0
  34. data/lib/rggen/builtins/bit_field/wo.rb +5 -0
  35. data/lib/rggen/builtins/global/address_width.rb +17 -0
  36. data/lib/rggen/builtins/global/data_width.rb +20 -0
  37. data/lib/rggen/builtins/loaders/configuration/json_loader.rb +7 -0
  38. data/lib/rggen/builtins/loaders/configuration/yaml_loader.rb +7 -0
  39. data/lib/rggen/builtins/loaders/register_map/csv_loader.rb +14 -0
  40. data/lib/rggen/builtins/loaders/register_map/xls_loader.rb +19 -0
  41. data/lib/rggen/builtins/loaders/register_map/xlsx_ods_loader.rb +24 -0
  42. data/lib/rggen/builtins/register/accessibility.rb +23 -0
  43. data/lib/rggen/builtins/register/address_decoder.erb +16 -0
  44. data/lib/rggen/builtins/register/address_decoder.rb +92 -0
  45. data/lib/rggen/builtins/register/array.rb +133 -0
  46. data/lib/rggen/builtins/register/field_model_creator.rb +10 -0
  47. data/lib/rggen/builtins/register/field_model_declarations.rb +7 -0
  48. data/lib/rggen/builtins/register/name.rb +26 -0
  49. data/lib/rggen/builtins/register/offset_address.rb +55 -0
  50. data/lib/rggen/builtins/register/read_data.rb +36 -0
  51. data/lib/rggen/builtins/register/reg_model_constructor.rb +17 -0
  52. data/lib/rggen/builtins/register/reg_model_creation.rb +64 -0
  53. data/lib/rggen/builtins/register/reg_model_declaration.rb +13 -0
  54. data/lib/rggen/builtins/register/reg_model_definition.rb +22 -0
  55. data/lib/rggen/builtins/register/shadow.rb +130 -0
  56. data/lib/rggen/builtins/register/shadow_index_configurator.rb +53 -0
  57. data/lib/rggen/builtins/register/uniqueness_validator.rb +48 -0
  58. data/lib/rggen/builtins/register_block/apb.erb +27 -0
  59. data/lib/rggen/builtins/register_block/apb.rb +20 -0
  60. data/lib/rggen/builtins/register_block/base_address.rb +64 -0
  61. data/lib/rggen/builtins/register_block/block_model_constructor.rb +14 -0
  62. data/lib/rggen/builtins/register_block/block_model_default_map_creator.rb +39 -0
  63. data/lib/rggen/builtins/register_block/block_model_definition.rb +18 -0
  64. data/lib/rggen/builtins/register_block/byte_size.rb +37 -0
  65. data/lib/rggen/builtins/register_block/clock_reset.rb +8 -0
  66. data/lib/rggen/builtins/register_block/host_if.rb +46 -0
  67. data/lib/rggen/builtins/register_block/module_definition.rb +13 -0
  68. data/lib/rggen/builtins/register_block/name.rb +26 -0
  69. data/lib/rggen/builtins/register_block/ral_package_definition.rb +19 -0
  70. data/lib/rggen/builtins/register_block/reg_model_creator.rb +14 -0
  71. data/lib/rggen/builtins/register_block/reg_model_declarations.rb +7 -0
  72. data/lib/rggen/builtins/register_block/response_mux.erb +14 -0
  73. data/lib/rggen/builtins/register_block/response_mux.rb +16 -0
  74. data/lib/rggen/builtins/register_block/signal_declarations.rb +9 -0
  75. data/lib/rggen/builtins.rb +52 -0
  76. data/lib/rggen/commands.rb +23 -0
  77. data/lib/rggen/core_components/configuration/configuration_factory.rb +23 -0
  78. data/lib/rggen/core_components/configuration/item_factory.rb +13 -0
  79. data/lib/rggen/core_components/configuration/raise_error.rb +11 -0
  80. data/lib/rggen/core_components/configuration/setup.rb +14 -0
  81. data/lib/rggen/core_components/ral/item.rb +16 -0
  82. data/lib/rggen/core_components/ral/setup.rb +19 -0
  83. data/lib/rggen/core_components/register_map/bit_field_factory.rb +11 -0
  84. data/lib/rggen/core_components/register_map/component.rb +12 -0
  85. data/lib/rggen/core_components/register_map/generic_map.rb +69 -0
  86. data/lib/rggen/core_components/register_map/item.rb +22 -0
  87. data/lib/rggen/core_components/register_map/item_factory.rb +13 -0
  88. data/lib/rggen/core_components/register_map/loader.rb +13 -0
  89. data/lib/rggen/core_components/register_map/raise_error.rb +17 -0
  90. data/lib/rggen/core_components/register_map/register_block_factory.rb +29 -0
  91. data/lib/rggen/core_components/register_map/register_factory.rb +18 -0
  92. data/lib/rggen/core_components/register_map/register_map_factory.rb +21 -0
  93. data/lib/rggen/core_components/register_map/setup.rb +33 -0
  94. data/lib/rggen/core_components/rtl/component.rb +28 -0
  95. data/lib/rggen/core_components/rtl/item.rb +83 -0
  96. data/lib/rggen/core_components/rtl/setup.rb +19 -0
  97. data/lib/rggen/core_components.rb +23 -0
  98. data/lib/rggen/core_extensions/facets.rb +17 -0
  99. data/lib/rggen/core_extensions/forwardable.rb +26 -0
  100. data/lib/rggen/core_extensions/integer.rb +5 -0
  101. data/lib/rggen/core_extensions/math.rb +7 -0
  102. data/lib/rggen/exceptions.rb +22 -0
  103. data/lib/rggen/generator.rb +185 -0
  104. data/lib/rggen/input_base/component.rb +19 -0
  105. data/lib/rggen/input_base/component_factory.rb +58 -0
  106. data/lib/rggen/input_base/item.rb +170 -0
  107. data/lib/rggen/input_base/item_factory.rb +13 -0
  108. data/lib/rggen/input_base/loader.rb +14 -0
  109. data/lib/rggen/input_base/regexp_patterns.rb +29 -0
  110. data/lib/rggen/output_base/code_block.rb +72 -0
  111. data/lib/rggen/output_base/code_utility.rb +44 -0
  112. data/lib/rggen/output_base/component.rb +88 -0
  113. data/lib/rggen/output_base/component_factory.rb +32 -0
  114. data/lib/rggen/output_base/item.rb +175 -0
  115. data/lib/rggen/output_base/item_factory.rb +6 -0
  116. data/lib/rggen/output_base/line.rb +28 -0
  117. data/lib/rggen/output_base/template_utility.rb +29 -0
  118. data/lib/rggen/output_base/verilog_utility/class_definition.rb +23 -0
  119. data/lib/rggen/output_base/verilog_utility/declaration.rb +70 -0
  120. data/lib/rggen/output_base/verilog_utility/identifier.rb +29 -0
  121. data/lib/rggen/output_base/verilog_utility/module_definition.rb +47 -0
  122. data/lib/rggen/output_base/verilog_utility/package_definition.rb +67 -0
  123. data/lib/rggen/output_base/verilog_utility/structure_definition.rb +52 -0
  124. data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +43 -0
  125. data/lib/rggen/output_base/verilog_utility.rb +66 -0
  126. data/lib/rggen/version.rb +6 -0
  127. data/lib/rggen.rb +65 -0
  128. data/ral/compile.f +4 -0
  129. data/ral/rggen_ral_block.svh +84 -0
  130. data/ral/rggen_ral_field.svh +47 -0
  131. data/ral/rggen_ral_macros.svh +22 -0
  132. data/ral/rggen_ral_map.svh +124 -0
  133. data/ral/rggen_ral_pkg.sv +14 -0
  134. data/ral/rggen_ral_reg.svh +52 -0
  135. data/ral/rggen_ral_shadow_reg.svh +188 -0
  136. data/rggen.gemspec +45 -0
  137. data/rtl/bit_field/rggen_bit_field_rw.sv +28 -0
  138. data/rtl/register/rggen_address_decoder.sv +49 -0
  139. data/rtl/register_block/rggen_host_if_apb.sv +40 -0
  140. data/rtl/register_block/rggen_response_mux.sv +82 -0
  141. data/sample/sample.csv +14 -0
  142. data/sample/sample.json +4 -0
  143. data/sample/sample.xls +0 -0
  144. data/sample/sample.xlsx +0 -0
  145. data/sample/sample.yaml +2 -0
  146. data/sample/sample_0.sv +285 -0
  147. data/sample/sample_0_ral_pkg.sv +99 -0
  148. data/sample/sample_1.sv +172 -0
  149. data/sample/sample_1_ral_pkg.sv +53 -0
  150. data/sample/sample_setup.rb +21 -0
  151. data/setup/default.rb +11 -0
  152. metadata +296 -0
@@ -0,0 +1,205 @@
1
+ list_item :bit_field, :type do
2
+ register_map do
3
+ item_base do
4
+ define_helpers do
5
+ def read_write
6
+ @readable = true
7
+ @writable = true
8
+ end
9
+
10
+ def read_only
11
+ @readable = true
12
+ @writable = false
13
+ end
14
+
15
+ def write_only
16
+ @readable = false
17
+ @writable = true
18
+ end
19
+
20
+ def reserved
21
+ @readable = false
22
+ @writable = false
23
+ end
24
+
25
+ def readable?
26
+ @readable.nil? || @readable
27
+ end
28
+
29
+ def writable?
30
+ @writable.nil? || @writable
31
+ end
32
+
33
+ def read_only?
34
+ readable? && !writable?
35
+ end
36
+
37
+ def write_only?
38
+ writable? && !readable?
39
+ end
40
+
41
+ def reserved?
42
+ !(readable? || writable?)
43
+ end
44
+
45
+ attr_setter :required_width
46
+
47
+ def full_width
48
+ :full_width
49
+ end
50
+
51
+ def need_initial_value
52
+ @need_initial_value = true
53
+ end
54
+
55
+ def need_initial_value?
56
+ @need_initial_value || false
57
+ end
58
+
59
+ def use_reference(options = {})
60
+ @use_reference = true
61
+ @reference_options = options
62
+ end
63
+
64
+ attr_reader :reference_options
65
+
66
+ def use_reference?
67
+ @use_reference || false
68
+ end
69
+
70
+ def same_width
71
+ :same_width
72
+ end
73
+ end
74
+
75
+ field :type
76
+ field :readable? , forward_to_helper: true
77
+ field :writable? , forward_to_helper: true
78
+ field :read_only? , forward_to_helper: true
79
+ field :write_only?, forward_to_helper: true
80
+ field :reserved? , forward_to_helper: true
81
+
82
+ class_delegator :full_width
83
+ class_delegator :need_initial_value?
84
+ class_delegator :use_reference?
85
+ class_delegator :reference_options
86
+ class_delegator :same_width
87
+
88
+ build do |cell|
89
+ @type = cell.to_sym.downcase
90
+ end
91
+
92
+ validate do
93
+ case
94
+ when width_mismatch?
95
+ error "#{required_width} bit(s) width required:" \
96
+ " #{bit_field.width} bit(s)"
97
+ when need_initial_value? && no_initial_value?
98
+ error 'no initial value'
99
+ when required_refercne_not_exist?
100
+ error 'reference bit field required'
101
+ when reference_width_mismatch?
102
+ error "#{required_reference_width} bit(s) reference bit field" \
103
+ " required: #{bit_field.reference.width}"
104
+ end
105
+ end
106
+
107
+ def width_mismatch?
108
+ return false if required_width.nil?
109
+ if required_width.respond_to?(:include?)
110
+ required_width.not.include?(bit_field.width)
111
+ else
112
+ bit_field.width != required_width
113
+ end
114
+ end
115
+
116
+ def required_width
117
+ width = self.class.required_width
118
+ return nil if width.nil?
119
+ return configuration.data_width if width == full_width
120
+ width
121
+ end
122
+
123
+ def no_initial_value?
124
+ !bit_field.initial_value?
125
+ end
126
+
127
+ def required_refercne_not_exist?
128
+ return false unless use_reference?
129
+ return false unless reference_options[:required]
130
+ return false if bit_field.has_reference?
131
+ true
132
+ end
133
+
134
+ def reference_width_mismatch?
135
+ return false unless use_reference?
136
+ return false unless bit_field.has_reference?
137
+ bit_field.reference.width != required_reference_width
138
+ end
139
+
140
+ def required_reference_width
141
+ return 1 unless reference_options[:width]
142
+ return bit_field.width if reference_options[:width] == same_width
143
+ reference_options[:width]
144
+ end
145
+ end
146
+
147
+ factory do
148
+ def select_target_item(cell)
149
+ type = cell.value.to_sym.downcase
150
+ @target_items.fetch(type) do
151
+ error "unknown bit field type: #{type}", cell
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ rtl do
158
+ item_base do
159
+ build do
160
+ next if bit_field.reserved?
161
+ logic :value, name: value_name, width: width, dimensions: dimensions
162
+ end
163
+
164
+ def value_name
165
+ "#{bit_field.name}_value"
166
+ end
167
+
168
+ delegate [:dimensions ] => :register
169
+ delegate [:width ] => :bit_field
170
+ delegate [:index, :local_index, :loop_variables] => :register
171
+ end
172
+
173
+ default_item do
174
+ end
175
+
176
+ factory do
177
+ def select_target_item(_, bit_field)
178
+ @target_items[bit_field.type]
179
+ end
180
+ end
181
+ end
182
+
183
+ ral do
184
+ item_base do
185
+ export :access
186
+
187
+ define_helpers do
188
+ attr_setter :access
189
+ end
190
+
191
+ def access
192
+ string((self.class.access || bit_field.type).to_s.upcase)
193
+ end
194
+ end
195
+
196
+ default_item do
197
+ end
198
+
199
+ factory do
200
+ def select_target_item(_, bit_field)
201
+ @target_items[bit_field.type]
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,5 @@
1
+ list_item :bit_field, :type, :wo do
2
+ register_map do
3
+ write_only
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ simple_item :global, :address_width do
2
+ configuration do
3
+ field :address_width, default: 32
4
+
5
+ build do |width|
6
+ begin
7
+ @address_width = Integer(width)
8
+ rescue
9
+ error "invalid value for address width: #{width.inspect}"
10
+ end
11
+
12
+ unless @address_width.positive?
13
+ error "zero/negative address width is not allowed: #{@address_width}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ simple_item :global, :data_width do
2
+ configuration do
3
+ field :data_width, default: 32
4
+ field :byte_width do
5
+ data_width / 8
6
+ end
7
+
8
+ build do |width|
9
+ begin
10
+ @data_width = Integer(width)
11
+ rescue
12
+ error "invalid value for data width: #{width.inspect}"
13
+ end
14
+
15
+ unless @data_width >= 8 && @data_width.pow2?
16
+ error "under 8/non-power of 2 data width is not allowed: #{@data_width}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ loader :configuration, :json do
2
+ require 'json'
3
+
4
+ def load_file(file)
5
+ JSON.parse(File.read(file))
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ loader :configuration, [:yml, :yaml] do
2
+ require 'yaml'
3
+
4
+ def load_file(file)
5
+ YAML.load_file(file)
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ loader :register_map, [:csv, :tsv] do
2
+ require 'csv'
3
+
4
+ def load_file(file)
5
+ create_map(file) do |map|
6
+ sheet_name = File.basename(file, '.*')
7
+ map[sheet_name] = CSV.read(file, col_sep: separator(file))
8
+ end
9
+ end
10
+
11
+ def separator(file)
12
+ (File.ext(file) == 'csv') ? ',' : "\t"
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ loader :register_map, :xls do
2
+ require 'spreadsheet'
3
+
4
+ def load_file(file)
5
+ create_map(file) do |map|
6
+ load_spreadsheet(file).each do |worksheet|
7
+ map[worksheet.name] = worksheet.rows
8
+ end
9
+ end
10
+ end
11
+
12
+ def load_spreadsheet(file)
13
+ Spreadsheet.open(file, 'rb') do |book|
14
+ book.worksheets.select do |worksheet|
15
+ worksheet.row_count > 0
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ loader :register_map, [:xlsx, :ods] do
2
+ require 'roo'
3
+
4
+ def load_file(file)
5
+ create_map(file) do |map|
6
+ load_spreadsheet(file).each do |sheet_name, sheet|
7
+ map[sheet_name] = sheet
8
+ end
9
+ end
10
+ end
11
+
12
+ def load_spreadsheet(file)
13
+ sheets = {}
14
+ Roo::Spreadsheet.open(file).each_with_pagename do |sheet_name, sheet|
15
+ next unless sheet.first_row
16
+ sheets[sheet_name] = 1.upto(sheet.last_row).map do |row|
17
+ 1.upto(sheet.last_column).map do |column|
18
+ sheet.cell(row, column)
19
+ end
20
+ end
21
+ end
22
+ sheets
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ simple_item :register, :accessibility do
2
+ register_map do
3
+ field :readable? do
4
+ register.bit_fields.any?(&:readable?)
5
+ end
6
+
7
+ field :writable? do
8
+ register.bit_fields.any?(&:writable?)
9
+ end
10
+
11
+ field :read_only? do
12
+ readable? && !writable?
13
+ end
14
+
15
+ field :write_only? do
16
+ writable? && !readable?
17
+ end
18
+
19
+ field :reserved? do
20
+ register.bit_fields.all?(&:reserved?)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ rggen_address_decoder #(
2
+ .READABLE (<%= readable %>),
3
+ .WRITABLE (<%= writable %>),
4
+ .ADDRESS_WIDTH (<%= local_address_width - address_lsb %>),
5
+ .START_ADDRESS (<%= start_address%>),
6
+ .END_ADDRESS (<%= end_address %>),
7
+ .USE_SHADOW_INDEX (<%= use_shadow_index %>),
8
+ .SHADOW_INDEX_WIDTH (<%= shadow_index_width %>),
9
+ .SHADOW_INDEX_VALUE (<%= shadow_index_value %>)
10
+ ) u_<%= register.name%>_address_decoder (
11
+ .i_read (<%= register_block.host_if.read %>),
12
+ .i_write (<%= register_block.host_if.write %>),
13
+ .i_address (<%= register_block.host_if.address[local_address_width - 1, address_lsb] %>),
14
+ .i_shadow_index (<%= (shadow? && shadow_index[loop_variables]) || shadow_index_value %>),
15
+ .o_select (<%= register_block.register_select[register.index] %>)
16
+ );
@@ -0,0 +1,92 @@
1
+ simple_item :register, :address_decoder do
2
+ rtl do
3
+ build do
4
+ next unless register.shadow?
5
+ logic :shadow_index,
6
+ name: "#{register.name}_shadow_index",
7
+ width: shadow_index_width,
8
+ dimensions: register.dimensions
9
+ end
10
+
11
+ generate_code :module_item do |buffer|
12
+ buffer << shadow_index_assignment << nl if shadow?
13
+ buffer << process_template
14
+ end
15
+
16
+ delegate [:local_address_width] => :register_block
17
+ delegate [:array?, :shadow?, :multiple?] => :register
18
+ delegate [:shadow_indexes, :loop_variables] => :register
19
+
20
+ def readable
21
+ ((register.readable? || register.reserved?) && 1) || 0
22
+ end
23
+
24
+ def writable
25
+ ((register.writable? || register.reserved?) && 1) || 0
26
+ end
27
+
28
+ def address_lsb
29
+ Math.clog2(configuration.byte_width)
30
+ end
31
+
32
+ def start_address
33
+ address_code(register.start_address)
34
+ end
35
+
36
+ def end_address
37
+ if array?
38
+ address = register.start_address + configuration.byte_width - 1
39
+ address_code(address)
40
+ else
41
+ address_code(register.end_address)
42
+ end
43
+ end
44
+
45
+ def address_code(address)
46
+ shift = address_lsb
47
+ base = hex(address >> shift, local_address_width - shift)
48
+ (array? && multiple? && "#{base} + #{register.local_index}") || base
49
+ end
50
+
51
+ def shadow_index_assignment
52
+ assign(
53
+ shadow_index[register.loop_variables],
54
+ concat(*shadow_index_fields.map(&:value))
55
+ )
56
+ end
57
+
58
+ def use_shadow_index
59
+ (shadow? && 1) || 0
60
+ end
61
+
62
+ def shadow_index_width
63
+ return 1 unless shadow?
64
+ shadow_index_fields.map(&:width).sum(0)
65
+ end
66
+
67
+ def shadow_index_value
68
+ return hex(0, 1) unless shadow?
69
+ concat(*shadow_index_values)
70
+ end
71
+
72
+ def shadow_index_fields
73
+ @shadow_index_fields ||= shadow_indexes.map do |index|
74
+ register_block.bit_fields.find do |bit_field|
75
+ bit_field.name == index.name
76
+ end
77
+ end
78
+ end
79
+
80
+ def shadow_index_values
81
+ variables = loop_variables
82
+ shadow_indexes.map.with_index do |index, i|
83
+ if index.value
84
+ hex(index.value, shadow_index_fields[i].width)
85
+ else
86
+ loop_variable = variables.shift
87
+ loop_variable[shadow_index_fields[i].width - 1, 0]
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,133 @@
1
+ simple_item :register, :array do
2
+ register_map do
3
+ field :array?
4
+ field :dimensions
5
+ field :count
6
+
7
+ input_pattern %r{\[(#{number}(?:,#{number})*)\]},
8
+ match_automatically: false
9
+
10
+ build do |cell|
11
+ @dimensions = parse_array_dimensions(cell)
12
+ @array = @dimensions.not_nil?
13
+ @count = (@dimensions && @dimensions.inject(&:*)) || 1
14
+ if @dimensions && @dimensions.any?(&:zero?)
15
+ error "0 is not allowed for array dimension: #{cell.inspect}"
16
+ end
17
+ end
18
+
19
+ validate do
20
+ case
21
+ when multi_dimensions_array_with_real_register?
22
+ error 'not use multi dimensions array with real register'
23
+ when mismatch_with_own_byte_size?
24
+ error "mismatches with own byte size(#{register.byte_size}):" \
25
+ " #{dimensions}"
26
+ end
27
+ end
28
+
29
+ def parse_array_dimensions(cell)
30
+ case
31
+ when cell.nil? || cell.empty?
32
+ nil
33
+ when pattern_match(cell)
34
+ captures.first.split(',').map(&method(:Integer))
35
+ else
36
+ error "invalid value for array dimension: #{cell.inspect}"
37
+ end
38
+ end
39
+
40
+ def multi_dimensions_array_with_real_register?
41
+ return false unless array?
42
+ return false if register.shadow?
43
+ register.multiple? && dimensions.size > 1
44
+ end
45
+
46
+ def mismatch_with_own_byte_size?
47
+ return false unless array?
48
+ return false if register.shadow?
49
+ register.byte_size != dimensions.first * configuration.byte_width
50
+ end
51
+ end
52
+
53
+ rtl do
54
+ export :index
55
+ export :local_index
56
+ export :loop_variables
57
+ export :loop_variable
58
+
59
+ def index
60
+ (register.array? && "#{base_index}+#{local_index}") || base_index
61
+ end
62
+
63
+ def local_index
64
+ return nil unless register.array?
65
+ local_index_terms(0).join('+')
66
+ end
67
+
68
+ def loop_variables
69
+ return nil unless register.array?
70
+ Array.new(register.dimensions.size) { |l| loop_variable(l) }
71
+ end
72
+
73
+ def loop_variable(level)
74
+ return nil unless register.array? && level < register.dimensions.size
75
+ @loop_variables ||= Hash.new do |h, l|
76
+ h[l] = create_identifier("g_#{loop_index(l)}")
77
+ end
78
+ @loop_variables[level]
79
+ end
80
+
81
+ def base_index
82
+ previous_registers.map(&:count).sum(0)
83
+ end
84
+
85
+ def local_index_terms(level)
86
+ if level < (register.dimensions.size - 1)
87
+ partial_count = register.dimensions[(level + 1)..-1].inject(:*)
88
+ term = [partial_count, '*', loop_variable(level)].join
89
+ local_index_terms(level + 1).unshift(term)
90
+ else
91
+ [loop_variable(level)]
92
+ end
93
+ end
94
+
95
+ def previous_registers
96
+ register_block.registers.take_while { |r| !register.equal?(r) }
97
+ end
98
+
99
+ generate_pre_code :module_item do |buffer|
100
+ register.dimensions.each_with_index do |dimension, level|
101
+ generate_for_begin_code(dimension, level, buffer)
102
+ end if register.array?
103
+ end
104
+
105
+ generate_post_code :module_item do |buffer|
106
+ register.dimensions.size.times do
107
+ generate_for_end_code(buffer)
108
+ end if register.array?
109
+ end
110
+
111
+ def generate_for_begin_code(dimension, level, buffer)
112
+ buffer << generate_for_header(dimension, level)
113
+ buffer << ' begin : '
114
+ buffer << block_name(level)
115
+ buffer << nl
116
+ buffer.indent += 2
117
+ end
118
+
119
+ def generate_for_end_code(buffer)
120
+ buffer.indent -= 2
121
+ buffer << 'end' << nl
122
+ end
123
+
124
+ def generate_for_header(dimension, level)
125
+ genvar = loop_variable(level)
126
+ "for (genvar #{genvar} = 0;#{genvar} < #{dimension};#{genvar}++)"
127
+ end
128
+
129
+ def block_name(level)
130
+ "gen_#{register.name}_#{level}"
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,10 @@
1
+ simple_item :register, :field_model_creator do
2
+ ral do
3
+ generate_code :reg_model_item do
4
+ function_definition :create_fields do |f|
5
+ f.return_type :void
6
+ f.body { register.generate_code(:field_model_creation, :top_down) }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ simple_item :register, :field_model_declarations do
2
+ ral do
3
+ generate_code :reg_model_item do |buffer|
4
+ register.generate_code(:field_model_declaration, :top_down, buffer)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ simple_item :register, :name do
2
+ register_map do
3
+ field :name
4
+
5
+ input_pattern %r{(#{variable_name})}
6
+
7
+ build do |cell|
8
+ @name = parse_name(cell)
9
+ error "repeated register name: #{@name}" if repeated_name?
10
+ end
11
+
12
+ def parse_name(cell)
13
+ if pattern_matched?
14
+ captures.first
15
+ else
16
+ error "invalid value for register name: #{cell.inspect}"
17
+ end
18
+ end
19
+
20
+ def repeated_name?
21
+ register_block.registers.any? do |register|
22
+ @name == register.name
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,55 @@
1
+ simple_item :register, :offset_address do
2
+ register_map do
3
+ field :start_address
4
+ field :end_address
5
+ field :byte_size do
6
+ end_address - start_address + 1
7
+ end
8
+ field :single? do
9
+ byte_size == configuration.byte_width
10
+ end
11
+ field :multiple? do
12
+ byte_size > configuration.byte_width
13
+ end
14
+
15
+ input_pattern %r{(#{number})(?:-(#{number}))?}
16
+
17
+ build do |cell|
18
+ @start_address, @end_address = parse_address(cell)
19
+ case
20
+ when @start_address >= @end_address
21
+ error "start address is equal to or greater than end address: #{cell}"
22
+ when unaligned_address?
23
+ error 'not aligned with data width' \
24
+ "(#{configuration.data_width}): #{cell}"
25
+ when @end_address > max_address
26
+ error 'exceeds the maximum offset address' \
27
+ "(0x#{max_address.to_s(16)}): #{cell}"
28
+ end
29
+ end
30
+
31
+ def parse_address(cell)
32
+ if pattern_matched?
33
+ addresses = captures.compact.map(&method(:Integer))
34
+ if addresses.size == 2
35
+ addresses
36
+ else
37
+ [addresses[0], addresses[0] + configuration.byte_width - 1]
38
+ end
39
+ else
40
+ error "invalid value for offset address: #{cell.inspect}"
41
+ end
42
+ end
43
+
44
+ def unaligned_address?
45
+ byte_width = configuration.byte_width
46
+ return true unless (@start_address + 0).multiple?(byte_width)
47
+ return true unless (@end_address + 1).multiple?(byte_width)
48
+ false
49
+ end
50
+
51
+ def max_address
52
+ register_block.byte_size - 1
53
+ end
54
+ end
55
+ end