rggen 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +91 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/bin/rggen +6 -0
- data/lib/rggen/base/component.rb +27 -0
- data/lib/rggen/base/component_factory.rb +46 -0
- data/lib/rggen/base/hierarchical_accessors.rb +87 -0
- data/lib/rggen/base/hierarchical_item_accessors.rb +79 -0
- data/lib/rggen/base/item.rb +24 -0
- data/lib/rggen/base/item_factory.rb +20 -0
- data/lib/rggen/builder/builder.rb +69 -0
- data/lib/rggen/builder/category.rb +52 -0
- data/lib/rggen/builder/component_entry.rb +50 -0
- data/lib/rggen/builder/component_store.rb +42 -0
- data/lib/rggen/builder/input_component_store.rb +25 -0
- data/lib/rggen/builder/item_store.rb +89 -0
- data/lib/rggen/builder/list_item_entry.rb +81 -0
- data/lib/rggen/builder/output_component_store.rb +13 -0
- data/lib/rggen/builder/simple_item_entry.rb +33 -0
- data/lib/rggen/builtins/bit_field/bit_assignment.rb +39 -0
- data/lib/rggen/builtins/bit_field/field_model_creation.rb +25 -0
- data/lib/rggen/builtins/bit_field/field_model_declaration.rb +9 -0
- data/lib/rggen/builtins/bit_field/initial_value.rb +36 -0
- data/lib/rggen/builtins/bit_field/name.rb +26 -0
- data/lib/rggen/builtins/bit_field/reference.rb +42 -0
- data/lib/rggen/builtins/bit_field/reserved.rb +9 -0
- data/lib/rggen/builtins/bit_field/ro.rb +19 -0
- data/lib/rggen/builtins/bit_field/rw.erb +13 -0
- data/lib/rggen/builtins/bit_field/rw.rb +25 -0
- data/lib/rggen/builtins/bit_field/type.rb +205 -0
- data/lib/rggen/builtins/bit_field/wo.rb +5 -0
- data/lib/rggen/builtins/global/address_width.rb +17 -0
- data/lib/rggen/builtins/global/data_width.rb +20 -0
- data/lib/rggen/builtins/loaders/configuration/json_loader.rb +7 -0
- data/lib/rggen/builtins/loaders/configuration/yaml_loader.rb +7 -0
- data/lib/rggen/builtins/loaders/register_map/csv_loader.rb +14 -0
- data/lib/rggen/builtins/loaders/register_map/xls_loader.rb +19 -0
- data/lib/rggen/builtins/loaders/register_map/xlsx_ods_loader.rb +24 -0
- data/lib/rggen/builtins/register/accessibility.rb +23 -0
- data/lib/rggen/builtins/register/address_decoder.erb +16 -0
- data/lib/rggen/builtins/register/address_decoder.rb +92 -0
- data/lib/rggen/builtins/register/array.rb +133 -0
- data/lib/rggen/builtins/register/field_model_creator.rb +10 -0
- data/lib/rggen/builtins/register/field_model_declarations.rb +7 -0
- data/lib/rggen/builtins/register/name.rb +26 -0
- data/lib/rggen/builtins/register/offset_address.rb +55 -0
- data/lib/rggen/builtins/register/read_data.rb +36 -0
- data/lib/rggen/builtins/register/reg_model_constructor.rb +17 -0
- data/lib/rggen/builtins/register/reg_model_creation.rb +64 -0
- data/lib/rggen/builtins/register/reg_model_declaration.rb +13 -0
- data/lib/rggen/builtins/register/reg_model_definition.rb +22 -0
- data/lib/rggen/builtins/register/shadow.rb +130 -0
- data/lib/rggen/builtins/register/shadow_index_configurator.rb +53 -0
- data/lib/rggen/builtins/register/uniqueness_validator.rb +48 -0
- data/lib/rggen/builtins/register_block/apb.erb +27 -0
- data/lib/rggen/builtins/register_block/apb.rb +20 -0
- data/lib/rggen/builtins/register_block/base_address.rb +64 -0
- data/lib/rggen/builtins/register_block/block_model_constructor.rb +14 -0
- data/lib/rggen/builtins/register_block/block_model_default_map_creator.rb +39 -0
- data/lib/rggen/builtins/register_block/block_model_definition.rb +18 -0
- data/lib/rggen/builtins/register_block/byte_size.rb +37 -0
- data/lib/rggen/builtins/register_block/clock_reset.rb +8 -0
- data/lib/rggen/builtins/register_block/host_if.rb +46 -0
- data/lib/rggen/builtins/register_block/module_definition.rb +13 -0
- data/lib/rggen/builtins/register_block/name.rb +26 -0
- data/lib/rggen/builtins/register_block/ral_package_definition.rb +19 -0
- data/lib/rggen/builtins/register_block/reg_model_creator.rb +14 -0
- data/lib/rggen/builtins/register_block/reg_model_declarations.rb +7 -0
- data/lib/rggen/builtins/register_block/response_mux.erb +14 -0
- data/lib/rggen/builtins/register_block/response_mux.rb +16 -0
- data/lib/rggen/builtins/register_block/signal_declarations.rb +9 -0
- data/lib/rggen/builtins.rb +52 -0
- data/lib/rggen/commands.rb +23 -0
- data/lib/rggen/core_components/configuration/configuration_factory.rb +23 -0
- data/lib/rggen/core_components/configuration/item_factory.rb +13 -0
- data/lib/rggen/core_components/configuration/raise_error.rb +11 -0
- data/lib/rggen/core_components/configuration/setup.rb +14 -0
- data/lib/rggen/core_components/ral/item.rb +16 -0
- data/lib/rggen/core_components/ral/setup.rb +19 -0
- data/lib/rggen/core_components/register_map/bit_field_factory.rb +11 -0
- data/lib/rggen/core_components/register_map/component.rb +12 -0
- data/lib/rggen/core_components/register_map/generic_map.rb +69 -0
- data/lib/rggen/core_components/register_map/item.rb +22 -0
- data/lib/rggen/core_components/register_map/item_factory.rb +13 -0
- data/lib/rggen/core_components/register_map/loader.rb +13 -0
- data/lib/rggen/core_components/register_map/raise_error.rb +17 -0
- data/lib/rggen/core_components/register_map/register_block_factory.rb +29 -0
- data/lib/rggen/core_components/register_map/register_factory.rb +18 -0
- data/lib/rggen/core_components/register_map/register_map_factory.rb +21 -0
- data/lib/rggen/core_components/register_map/setup.rb +33 -0
- data/lib/rggen/core_components/rtl/component.rb +28 -0
- data/lib/rggen/core_components/rtl/item.rb +83 -0
- data/lib/rggen/core_components/rtl/setup.rb +19 -0
- data/lib/rggen/core_components.rb +23 -0
- data/lib/rggen/core_extensions/facets.rb +17 -0
- data/lib/rggen/core_extensions/forwardable.rb +26 -0
- data/lib/rggen/core_extensions/integer.rb +5 -0
- data/lib/rggen/core_extensions/math.rb +7 -0
- data/lib/rggen/exceptions.rb +22 -0
- data/lib/rggen/generator.rb +185 -0
- data/lib/rggen/input_base/component.rb +19 -0
- data/lib/rggen/input_base/component_factory.rb +58 -0
- data/lib/rggen/input_base/item.rb +170 -0
- data/lib/rggen/input_base/item_factory.rb +13 -0
- data/lib/rggen/input_base/loader.rb +14 -0
- data/lib/rggen/input_base/regexp_patterns.rb +29 -0
- data/lib/rggen/output_base/code_block.rb +72 -0
- data/lib/rggen/output_base/code_utility.rb +44 -0
- data/lib/rggen/output_base/component.rb +88 -0
- data/lib/rggen/output_base/component_factory.rb +32 -0
- data/lib/rggen/output_base/item.rb +175 -0
- data/lib/rggen/output_base/item_factory.rb +6 -0
- data/lib/rggen/output_base/line.rb +28 -0
- data/lib/rggen/output_base/template_utility.rb +29 -0
- data/lib/rggen/output_base/verilog_utility/class_definition.rb +23 -0
- data/lib/rggen/output_base/verilog_utility/declaration.rb +70 -0
- data/lib/rggen/output_base/verilog_utility/identifier.rb +29 -0
- data/lib/rggen/output_base/verilog_utility/module_definition.rb +47 -0
- data/lib/rggen/output_base/verilog_utility/package_definition.rb +67 -0
- data/lib/rggen/output_base/verilog_utility/structure_definition.rb +52 -0
- data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +43 -0
- data/lib/rggen/output_base/verilog_utility.rb +66 -0
- data/lib/rggen/version.rb +6 -0
- data/lib/rggen.rb +65 -0
- data/ral/compile.f +4 -0
- data/ral/rggen_ral_block.svh +84 -0
- data/ral/rggen_ral_field.svh +47 -0
- data/ral/rggen_ral_macros.svh +22 -0
- data/ral/rggen_ral_map.svh +124 -0
- data/ral/rggen_ral_pkg.sv +14 -0
- data/ral/rggen_ral_reg.svh +52 -0
- data/ral/rggen_ral_shadow_reg.svh +188 -0
- data/rggen.gemspec +45 -0
- data/rtl/bit_field/rggen_bit_field_rw.sv +28 -0
- data/rtl/register/rggen_address_decoder.sv +49 -0
- data/rtl/register_block/rggen_host_if_apb.sv +40 -0
- data/rtl/register_block/rggen_response_mux.sv +82 -0
- data/sample/sample.csv +14 -0
- data/sample/sample.json +4 -0
- data/sample/sample.xls +0 -0
- data/sample/sample.xlsx +0 -0
- data/sample/sample.yaml +2 -0
- data/sample/sample_0.sv +285 -0
- data/sample/sample_0_ral_pkg.sv +99 -0
- data/sample/sample_1.sv +172 -0
- data/sample/sample_1_ral_pkg.sv +53 -0
- data/sample/sample_setup.rb +21 -0
- data/setup/default.rb +11 -0
- 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,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,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,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
|