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.
- 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
|