rggen 0.3.0

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