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,36 @@
|
|
1
|
+
simple_item :register, :read_data do
|
2
|
+
rtl do
|
3
|
+
generate_code :module_item do |buffer|
|
4
|
+
buffer << assign(register_read_data, read_data) << nl
|
5
|
+
end
|
6
|
+
|
7
|
+
def register_read_data
|
8
|
+
register_block.register_read_data[register.index]
|
9
|
+
end
|
10
|
+
|
11
|
+
def read_data
|
12
|
+
if register.readable?
|
13
|
+
concat(*read_data_expressions)
|
14
|
+
else
|
15
|
+
hex(0, configuration.data_width)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_data_expressions
|
20
|
+
last_lsb = configuration.data_width
|
21
|
+
expressions = []
|
22
|
+
readable_fields.each do |field|
|
23
|
+
padding_bits = last_lsb - field.msb - 1
|
24
|
+
last_lsb = field.lsb
|
25
|
+
expressions << hex(0, padding_bits) if padding_bits > 0
|
26
|
+
expressions << field.value[register.loop_variables]
|
27
|
+
end
|
28
|
+
expressions << hex(0, last_lsb) if last_lsb > 0
|
29
|
+
expressions
|
30
|
+
end
|
31
|
+
|
32
|
+
def readable_fields
|
33
|
+
register.bit_fields.select(&:readable?).sort_by(&:msb).reverse
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
simple_item :register, :reg_model_constructor do
|
2
|
+
ral do
|
3
|
+
generate_code :reg_model_item do
|
4
|
+
function_definition :new do |f|
|
5
|
+
f.arguments [
|
6
|
+
argument(:name, data_type: :string, default: string(register.name))
|
7
|
+
]
|
8
|
+
f.body { "super.new(name, #{bits}, 0);" }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def bits
|
13
|
+
max_msb = register.bit_fields.map(&:msb).max
|
14
|
+
((max_msb + 8) / 8) * 8
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
simple_item :register, :reg_model_creation do
|
2
|
+
ral do
|
3
|
+
delegate [:byte_width] => :configuration
|
4
|
+
delegate [:local_address_width] => :register_block
|
5
|
+
delegate [:name, :dimensions, :array?, :shadow?] => :register
|
6
|
+
|
7
|
+
generate_code :reg_model_creation do |buffer|
|
8
|
+
foreach_header(buffer) if array?
|
9
|
+
model_creation(buffer)
|
10
|
+
foreach_footer(buffer) if array?
|
11
|
+
end
|
12
|
+
|
13
|
+
def foreach_header(buffer)
|
14
|
+
buffer << "foreach (#{name}[#{loop_varibles.join(', ')}]) begin" << nl
|
15
|
+
buffer.indent += 2
|
16
|
+
end
|
17
|
+
|
18
|
+
def model_creation(buffer)
|
19
|
+
buffer << "`rggen_ral_create_reg_model(#{arguments.join(', ')})" << nl
|
20
|
+
end
|
21
|
+
|
22
|
+
def foreach_footer(buffer)
|
23
|
+
buffer.indent -= 2
|
24
|
+
buffer << 'end' << nl
|
25
|
+
end
|
26
|
+
|
27
|
+
def arguments
|
28
|
+
[handle, string(name), array_index, offset_address, rights, unmapped]
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle
|
32
|
+
create_identifier(name)[loop_varibles]
|
33
|
+
end
|
34
|
+
|
35
|
+
def array_index
|
36
|
+
return '\'{}' unless array?
|
37
|
+
array(*loop_varibles)
|
38
|
+
end
|
39
|
+
|
40
|
+
def offset_address
|
41
|
+
base = hex(register.start_address, local_address_width)
|
42
|
+
if !array? || shadow?
|
43
|
+
base
|
44
|
+
else
|
45
|
+
"#{base} + #{byte_width} * #{loop_varibles.first}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def rights
|
50
|
+
return string(:RO) if register.read_only?
|
51
|
+
return string(:WO) if register.write_only?
|
52
|
+
string(:RW)
|
53
|
+
end
|
54
|
+
|
55
|
+
def unmapped
|
56
|
+
(shadow? && 1) || 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def loop_varibles
|
60
|
+
return nil unless array?
|
61
|
+
@loop_varibles ||= Array.new(dimensions.size, &method(:loop_index))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
simple_item :register, :reg_model_declaration do
|
2
|
+
ral do
|
3
|
+
delegate [:model_name, :name, :dimensions] => :register
|
4
|
+
|
5
|
+
generate_code :reg_model_declaration do |buffer|
|
6
|
+
buffer << declaration << semicolon << nl
|
7
|
+
end
|
8
|
+
|
9
|
+
def declaration
|
10
|
+
model_declaration(model_name, name, dimensions: dimensions)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
simple_item :register, :reg_model_definition do
|
2
|
+
ral do
|
3
|
+
export :model_name
|
4
|
+
|
5
|
+
generate_code :package_item do
|
6
|
+
class_definition model_name do |c|
|
7
|
+
c.base base_model
|
8
|
+
c.body do |buffer|
|
9
|
+
register.generate_code(:reg_model_item, :top_down, buffer)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def model_name
|
15
|
+
"#{register.name}_reg_model"
|
16
|
+
end
|
17
|
+
|
18
|
+
def base_model
|
19
|
+
(register.shadow? && :rggen_ral_shadow_reg) || :rggen_ral_reg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
simple_item :register, :shadow do
|
2
|
+
register_map do
|
3
|
+
ShadowIndexEntry = Struct.new(:name, :value) do
|
4
|
+
def initialize(name, value)
|
5
|
+
self.name = name
|
6
|
+
self.value = value && Integer(value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
return false unless name == other.name
|
11
|
+
return true if [value, other.value].any?(&:nil?)
|
12
|
+
value == other.value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
field :shadow?
|
17
|
+
field :shadow_indexes
|
18
|
+
|
19
|
+
input_pattern %r{(#{variable_name})(?::(#{number}))?}
|
20
|
+
|
21
|
+
build do |cell|
|
22
|
+
@shadow_indexes = parse_shadow_indexes(cell)
|
23
|
+
@shadow = @shadow_indexes.not_nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
validate do
|
27
|
+
next unless shadow?
|
28
|
+
check_using_shadow_register_only
|
29
|
+
check_index_fields
|
30
|
+
check_size_of_array_index_fields
|
31
|
+
check_array_index_values
|
32
|
+
check_specific_value_index_values
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_shadow_indexes(cell)
|
36
|
+
return nil if cell.nil? || cell.empty?
|
37
|
+
cell.split(/[,\n]/).map do |entry|
|
38
|
+
if pattern_match(entry)
|
39
|
+
ShadowIndexEntry.new(captures[0], captures[1])
|
40
|
+
else
|
41
|
+
error "invalid value for shadow index: #{cell.inspect}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def check_using_shadow_register_only
|
47
|
+
return unless register.multiple? && register.array?
|
48
|
+
error 'not use real array and shadow register on the same register'
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_index_fields
|
52
|
+
shadow_indexes.each do |entry|
|
53
|
+
case
|
54
|
+
when use_same_index_field_more_than_once?(entry.name)
|
55
|
+
error "not use the same index field more than once: #{entry.name}"
|
56
|
+
when not_find_shadow_index_field?(entry)
|
57
|
+
error "no such shadow index field: #{entry.name}"
|
58
|
+
when use_own_bit_field?(entry)
|
59
|
+
error 'own bit field is specified for shadow index field:' \
|
60
|
+
" #{entry.name}"
|
61
|
+
when use_arrayed_bit_field?(entry)
|
62
|
+
error 'arrayed bit field is specified for shadow index field:' \
|
63
|
+
" #{entry.name}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def use_same_index_field_more_than_once?(name)
|
69
|
+
shadow_indexes.count { |entry| entry.name == name } > 1
|
70
|
+
end
|
71
|
+
|
72
|
+
def not_find_shadow_index_field?(entry)
|
73
|
+
shadow_index_bit_field[entry.name].nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
def use_own_bit_field?(entry)
|
77
|
+
register.bit_fields.map(&:name).include?(entry.name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def use_arrayed_bit_field?(entry)
|
81
|
+
shadow_index_bit_field[entry.name].register.array?
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_size_of_array_index_fields
|
85
|
+
return if size_of_dimensions == array_indexes.size
|
86
|
+
error 'not match number of array dimensions and' \
|
87
|
+
' number of array index fields'
|
88
|
+
end
|
89
|
+
|
90
|
+
def check_array_index_values
|
91
|
+
array_indexes.each_with_index do |entry, i|
|
92
|
+
next if register.dimensions[i] <= (maximum_value(entry.name) + 1)
|
93
|
+
error "exceeds maximum array size specified by #{entry.name}" \
|
94
|
+
"(#{maximum_value(entry.name) + 1}): #{register.dimensions[i]}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def check_specific_value_index_values
|
99
|
+
specific_value_indexes.each do |entry|
|
100
|
+
next if entry.value <= maximum_value(entry.name)
|
101
|
+
error "exceeds maximum value of #{entry.name}" \
|
102
|
+
"(#{maximum_value(entry.name)}): #{entry.value}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def size_of_dimensions
|
107
|
+
(register.array? && register.dimensions.size) || 0
|
108
|
+
end
|
109
|
+
|
110
|
+
def array_indexes
|
111
|
+
shadow_indexes.select { |entry| entry.value.nil? }
|
112
|
+
end
|
113
|
+
|
114
|
+
def specific_value_indexes
|
115
|
+
shadow_indexes.select { |entry| entry.value.not_nil? }
|
116
|
+
end
|
117
|
+
|
118
|
+
def maximum_value(index_name)
|
119
|
+
2**shadow_index_bit_field[index_name].width - 1
|
120
|
+
end
|
121
|
+
|
122
|
+
def shadow_index_bit_field
|
123
|
+
@shadow_index_bit_field ||= Hash.new do |hash, index_name|
|
124
|
+
hash[index_name] = register_block.bit_fields.find do |bit_field|
|
125
|
+
bit_field.name == index_name && !bit_field.reserved?
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
simple_item :register, :shadow_index_configurator do
|
2
|
+
ral do
|
3
|
+
generate_code :reg_model_item do
|
4
|
+
function_definition :configure_shadow_indexes do |f|
|
5
|
+
f.return_type :void
|
6
|
+
f.body { |code| function_body(code) }
|
7
|
+
end if register.shadow?
|
8
|
+
end
|
9
|
+
|
10
|
+
def function_body(code)
|
11
|
+
register.shadow_indexes.each do |shadow_index|
|
12
|
+
code << "set_shadow_index(#{arguments(shadow_index)});" << nl
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def arguments(shadow_index)
|
17
|
+
[
|
18
|
+
parent_name(shadow_index),
|
19
|
+
index_name(shadow_index),
|
20
|
+
index_value(shadow_index)
|
21
|
+
].join(', ')
|
22
|
+
end
|
23
|
+
|
24
|
+
def parent_name(shadow_index)
|
25
|
+
parent_register = fild_parent_register(shadow_index.name)
|
26
|
+
string(parent_register.name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def fild_parent_register(index_name)
|
30
|
+
index_field = register_block.bit_fields.find do |bit_field|
|
31
|
+
bit_field.name == index_name
|
32
|
+
end
|
33
|
+
index_field.register
|
34
|
+
end
|
35
|
+
|
36
|
+
def index_name(shadow_index)
|
37
|
+
string(shadow_index.name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def index_value(shadow_index)
|
41
|
+
if shadow_index.value
|
42
|
+
shadow_index.value
|
43
|
+
else
|
44
|
+
"indexes[#{array_index}]"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def array_index
|
49
|
+
@array_index ||= -1
|
50
|
+
@array_index += 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
simple_item :register, :uniqueness_validator do
|
2
|
+
register_map do
|
3
|
+
validate do
|
4
|
+
previous_registers.each do |previous_register|
|
5
|
+
validate_uniqueness(previous_register)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def previous_registers
|
10
|
+
register_block.registers.take_while { |r| !r.equal?(register) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_uniqueness(previous_register)
|
14
|
+
case
|
15
|
+
when overlap_offset_address?(previous_register)
|
16
|
+
error 'offset address is not unique', error_position(:start_address)
|
17
|
+
when overlap_shadow_indexes?(previous_register)
|
18
|
+
error 'shadow indexes is not unique', error_position(:shadow_indexes)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def overlap_offset_address?(previous_register)
|
23
|
+
return false if [previous_register, register].all?(&:shadow?)
|
24
|
+
overlap_address_range?(register, previous_register)
|
25
|
+
end
|
26
|
+
|
27
|
+
def overlap_address_range?(lhs, rhs)
|
28
|
+
lhs_range = lhs.start_address..lhs.end_address
|
29
|
+
rhs_range = rhs.start_address..rhs.end_address
|
30
|
+
lhs_range.overlap?(rhs_range)
|
31
|
+
end
|
32
|
+
|
33
|
+
def overlap_shadow_indexes?(previous_register)
|
34
|
+
return false unless overlap_address_range?(register, previous_register)
|
35
|
+
return true unless unique_shadw_indexes?(register, previous_register)
|
36
|
+
return true unless unique_shadw_indexes?(previous_register, register)
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def unique_shadw_indexes?(lhs, rhs)
|
41
|
+
lhs.shadow_indexes.any?(&rhs.shadow_indexes.method(:exclude?))
|
42
|
+
end
|
43
|
+
|
44
|
+
def error_position(field)
|
45
|
+
register.items.find { |i| i.fields.include?(field) }.position
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
rggen_host_if_apb #(
|
2
|
+
.DATA_WIDTH (<%= configuration.data_width %>),
|
3
|
+
.HOST_ADDRESS_WIDTH (<%= configuration.address_width %>),
|
4
|
+
.LOCAL_ADDRESS_WIDTH (<%= register_block.local_address_width %>)
|
5
|
+
) u_host_if (
|
6
|
+
.clk (<%= register_block.clock %>),
|
7
|
+
.rst_n (<%= register_block.reset %>),
|
8
|
+
.i_paddr (<%= apb.paddr %>),
|
9
|
+
.i_pprot (<%= apb.pprot %>),
|
10
|
+
.i_psel (<%= apb.psel %>),
|
11
|
+
.i_penable (<%= apb.penable %>),
|
12
|
+
.i_pwrite (<%= apb.pwrite %>),
|
13
|
+
.i_pwdata (<%= apb.pwdata %>),
|
14
|
+
.i_pstrb (<%= apb.pstrb %>),
|
15
|
+
.o_pready (<%= apb.pready %>),
|
16
|
+
.o_prdata (<%= apb.prdata %>),
|
17
|
+
.o_pslverr (<%= apb.pslverr %>),
|
18
|
+
.o_command_valid (<%= host_if.command_valid %>),
|
19
|
+
.o_write (<%= host_if.write %>),
|
20
|
+
.o_read (<%= host_if.read %>),
|
21
|
+
.o_address (<%= host_if.address %>),
|
22
|
+
.o_write_data (<%= host_if.write_data %>),
|
23
|
+
.o_write_mask (<%= host_if.write_mask %>),
|
24
|
+
.i_response_ready (<%= host_if.response_ready %>),
|
25
|
+
.i_read_data (<%= host_if.read_data %>),
|
26
|
+
.i_status (<%= host_if.status %>)
|
27
|
+
);
|
@@ -0,0 +1,20 @@
|
|
1
|
+
list_item :register_block, :host_if, :apb do
|
2
|
+
rtl do
|
3
|
+
build do
|
4
|
+
group(:apb) do
|
5
|
+
input :paddr , name: 'i_paddr' , width: configuration.address_width
|
6
|
+
input :pprot , name: 'i_pprot' , width: 3
|
7
|
+
input :psel , name: 'i_psel' , width: 1
|
8
|
+
input :penable, name: 'i_penable', width: 1
|
9
|
+
input :pwrite , name: 'i_pwrite' , width: 1
|
10
|
+
input :pwdata , name: 'i_pwdata' , width: configuration.data_width
|
11
|
+
input :pstrb , name: 'i_pstrb' , width: configuration.byte_width
|
12
|
+
output :pready , name: 'o_pready' , width: 1
|
13
|
+
output :prdata , name: 'o_prdata' , width: configuration.data_width
|
14
|
+
output :pslverr, name: 'o_pslverr', width: 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
generate_code_from_template :module_item
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
simple_item :register_block, :base_address do
|
2
|
+
register_map do
|
3
|
+
field :start_address
|
4
|
+
field :end_address
|
5
|
+
field :byte_size
|
6
|
+
field :local_address_width
|
7
|
+
|
8
|
+
input_pattern %r{(#{number})-(#{number})}
|
9
|
+
|
10
|
+
build do |cell|
|
11
|
+
parse_address(cell)
|
12
|
+
case
|
13
|
+
when @start_address >= @end_address
|
14
|
+
error "start address is equal to or greater than end address: #{cell}"
|
15
|
+
when not_aligned_with_data_width?
|
16
|
+
error 'not aligned with data width' \
|
17
|
+
"(#{configuration.data_width}): #{cell}"
|
18
|
+
when not_aligned_with_local_address_width?
|
19
|
+
error 'not aligned with local address width' \
|
20
|
+
"(#{@local_address_width}): #{cell}"
|
21
|
+
when @end_address > max_address
|
22
|
+
error 'exceeds the maximum base address' \
|
23
|
+
"(0x#{max_address.to_s(16)}): #{cell}"
|
24
|
+
when overlapped_address?
|
25
|
+
error "overlapped base address: #{cell}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_address(cell)
|
30
|
+
if pattern_matched?
|
31
|
+
@start_address = Integer(captures[0])
|
32
|
+
@end_address = Integer(captures[1])
|
33
|
+
@byte_size = @end_address - @start_address + 1
|
34
|
+
@local_address_width = Math.clog2(@byte_size) if @byte_size > 0
|
35
|
+
else
|
36
|
+
error "invalid value for base address: #{cell.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def not_aligned_with_data_width?
|
41
|
+
byte_width = configuration.byte_width
|
42
|
+
return true unless (@start_address + 0).multiple?(byte_width)
|
43
|
+
return true unless (@end_address + 1).multiple?(byte_width)
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def not_aligned_with_local_address_width?
|
48
|
+
window_size = 2**@local_address_width
|
49
|
+
return true unless @start_address.multiple?(window_size)
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
def max_address
|
54
|
+
2**configuration.address_width - 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def overlapped_address?
|
58
|
+
own_range = @start_address..@end_address
|
59
|
+
register_map.register_blocks.any? do |block|
|
60
|
+
own_range.overlap?(block.start_address..block.end_address)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
simple_item :register_block, :block_model_constructor do
|
2
|
+
ral do
|
3
|
+
delegate [:name] => :register_block
|
4
|
+
|
5
|
+
generate_code :block_model_item do
|
6
|
+
function_definition :new do |f|
|
7
|
+
f.arguments [
|
8
|
+
argument(:name, data_type: :string, default: string(name))
|
9
|
+
]
|
10
|
+
f.body { 'super.new(name);' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
simple_item :register_block, :block_model_default_map_creator do
|
2
|
+
ral do
|
3
|
+
generate_code :block_model_item do
|
4
|
+
function_definition :create_default_map do |f|
|
5
|
+
f.return_type :uvm_reg_map
|
6
|
+
f.body do |code|
|
7
|
+
code << :return
|
8
|
+
code << space
|
9
|
+
code << "create_map(#{arguments.join(', ')})"
|
10
|
+
code << semicolon
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def arguments
|
16
|
+
[name, base_address, n_bytes, endian, byte_addressing]
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
string(:default_map)
|
21
|
+
end
|
22
|
+
|
23
|
+
def base_address
|
24
|
+
0
|
25
|
+
end
|
26
|
+
|
27
|
+
def n_bytes
|
28
|
+
configuration.byte_width
|
29
|
+
end
|
30
|
+
|
31
|
+
def endian
|
32
|
+
:UVM_LITTLE_ENDIAN
|
33
|
+
end
|
34
|
+
|
35
|
+
def byte_addressing
|
36
|
+
1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
simple_item :register_block, :block_model_definition do
|
2
|
+
ral do
|
3
|
+
generate_code :package_item do
|
4
|
+
class_definition model_name do |c|
|
5
|
+
c.base :rggen_ral_block
|
6
|
+
c.body { |code| body_code(code) }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def model_name
|
11
|
+
"#{register_block.name}_block_model"
|
12
|
+
end
|
13
|
+
|
14
|
+
def body_code(code)
|
15
|
+
register_block.generate_code(:block_model_item, :top_down, code)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
simple_item :register_block, :byte_size do
|
2
|
+
register_map do
|
3
|
+
field :byte_size
|
4
|
+
field :local_address_width
|
5
|
+
|
6
|
+
build do |cell|
|
7
|
+
begin
|
8
|
+
@byte_size = Integer(cell)
|
9
|
+
rescue
|
10
|
+
error "invalid value for byte size: #{cell.inspect}"
|
11
|
+
end
|
12
|
+
|
13
|
+
case
|
14
|
+
when @byte_size.not.positive?
|
15
|
+
error "zero or negative value is not allowed for byte size: #{cell}"
|
16
|
+
when @byte_size.not.multiple?(configuration.byte_width)
|
17
|
+
error 'not aligned with data width' \
|
18
|
+
"(#{configuration.data_width}): #{cell}"
|
19
|
+
when total_byte_size > upper_bound
|
20
|
+
error 'exceeds upper bound of total byte size' \
|
21
|
+
"(#{upper_bound}): #{total_byte_size}"
|
22
|
+
end
|
23
|
+
|
24
|
+
@local_address_width = Math.clog2(@byte_size)
|
25
|
+
end
|
26
|
+
|
27
|
+
def upper_bound
|
28
|
+
2**configuration.address_width
|
29
|
+
end
|
30
|
+
|
31
|
+
def total_byte_size
|
32
|
+
register_map.register_blocks.inject(@byte_size) do |total, block|
|
33
|
+
total + block.byte_size
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
list_item :register_block, :host_if do
|
2
|
+
shared_context do
|
3
|
+
attr_accessor :enabled_host_ifs
|
4
|
+
end
|
5
|
+
|
6
|
+
configuration do
|
7
|
+
item_class do
|
8
|
+
field :host_if do
|
9
|
+
@host_if || shared_context.enabled_host_ifs.first
|
10
|
+
end
|
11
|
+
|
12
|
+
build do |value|
|
13
|
+
@host_if = shared_context.enabled_host_ifs.find do |host_if|
|
14
|
+
host_if.to_sym.casecmp(value.to_sym) == 0
|
15
|
+
end
|
16
|
+
error "unknown host interface: #{value}" if @host_if.nil?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
rtl do
|
22
|
+
shared_context.enabled_host_ifs = @enabled_items
|
23
|
+
|
24
|
+
item_base do
|
25
|
+
build do
|
26
|
+
group(:host_if) do
|
27
|
+
logic :command_valid , width: 1
|
28
|
+
logic :write , width: 1
|
29
|
+
logic :read , width: 1
|
30
|
+
logic :address , width: register_block.local_address_width
|
31
|
+
logic :write_data , width: configuration.data_width
|
32
|
+
logic :write_mask , width: configuration.data_width
|
33
|
+
logic :response_ready, width: 1
|
34
|
+
logic :read_data , width: configuration.data_width
|
35
|
+
logic :status , width: 2
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
factory do
|
41
|
+
def select_target_item(configuration, _register_block)
|
42
|
+
@target_items[configuration.host_if]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
define_simple_item :register_block, :module_definition do
|
2
|
+
rtl do
|
3
|
+
write_file '<%= register_block.name %>.sv' do
|
4
|
+
module_definition register_block.name do |m|
|
5
|
+
m.parameters register_block.parameter_declarations
|
6
|
+
m.ports register_block.port_declarations
|
7
|
+
m.body do |code|
|
8
|
+
register_block.generate_code(:module_item, :top_down, code)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|