rggen 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +7 -0
  3. data/.rubocop_todo.yml +91 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +31 -0
  7. data/bin/rggen +6 -0
  8. data/lib/rggen/base/component.rb +27 -0
  9. data/lib/rggen/base/component_factory.rb +46 -0
  10. data/lib/rggen/base/hierarchical_accessors.rb +87 -0
  11. data/lib/rggen/base/hierarchical_item_accessors.rb +79 -0
  12. data/lib/rggen/base/item.rb +24 -0
  13. data/lib/rggen/base/item_factory.rb +20 -0
  14. data/lib/rggen/builder/builder.rb +69 -0
  15. data/lib/rggen/builder/category.rb +52 -0
  16. data/lib/rggen/builder/component_entry.rb +50 -0
  17. data/lib/rggen/builder/component_store.rb +42 -0
  18. data/lib/rggen/builder/input_component_store.rb +25 -0
  19. data/lib/rggen/builder/item_store.rb +89 -0
  20. data/lib/rggen/builder/list_item_entry.rb +81 -0
  21. data/lib/rggen/builder/output_component_store.rb +13 -0
  22. data/lib/rggen/builder/simple_item_entry.rb +33 -0
  23. data/lib/rggen/builtins/bit_field/bit_assignment.rb +39 -0
  24. data/lib/rggen/builtins/bit_field/field_model_creation.rb +25 -0
  25. data/lib/rggen/builtins/bit_field/field_model_declaration.rb +9 -0
  26. data/lib/rggen/builtins/bit_field/initial_value.rb +36 -0
  27. data/lib/rggen/builtins/bit_field/name.rb +26 -0
  28. data/lib/rggen/builtins/bit_field/reference.rb +42 -0
  29. data/lib/rggen/builtins/bit_field/reserved.rb +9 -0
  30. data/lib/rggen/builtins/bit_field/ro.rb +19 -0
  31. data/lib/rggen/builtins/bit_field/rw.erb +13 -0
  32. data/lib/rggen/builtins/bit_field/rw.rb +25 -0
  33. data/lib/rggen/builtins/bit_field/type.rb +205 -0
  34. data/lib/rggen/builtins/bit_field/wo.rb +5 -0
  35. data/lib/rggen/builtins/global/address_width.rb +17 -0
  36. data/lib/rggen/builtins/global/data_width.rb +20 -0
  37. data/lib/rggen/builtins/loaders/configuration/json_loader.rb +7 -0
  38. data/lib/rggen/builtins/loaders/configuration/yaml_loader.rb +7 -0
  39. data/lib/rggen/builtins/loaders/register_map/csv_loader.rb +14 -0
  40. data/lib/rggen/builtins/loaders/register_map/xls_loader.rb +19 -0
  41. data/lib/rggen/builtins/loaders/register_map/xlsx_ods_loader.rb +24 -0
  42. data/lib/rggen/builtins/register/accessibility.rb +23 -0
  43. data/lib/rggen/builtins/register/address_decoder.erb +16 -0
  44. data/lib/rggen/builtins/register/address_decoder.rb +92 -0
  45. data/lib/rggen/builtins/register/array.rb +133 -0
  46. data/lib/rggen/builtins/register/field_model_creator.rb +10 -0
  47. data/lib/rggen/builtins/register/field_model_declarations.rb +7 -0
  48. data/lib/rggen/builtins/register/name.rb +26 -0
  49. data/lib/rggen/builtins/register/offset_address.rb +55 -0
  50. data/lib/rggen/builtins/register/read_data.rb +36 -0
  51. data/lib/rggen/builtins/register/reg_model_constructor.rb +17 -0
  52. data/lib/rggen/builtins/register/reg_model_creation.rb +64 -0
  53. data/lib/rggen/builtins/register/reg_model_declaration.rb +13 -0
  54. data/lib/rggen/builtins/register/reg_model_definition.rb +22 -0
  55. data/lib/rggen/builtins/register/shadow.rb +130 -0
  56. data/lib/rggen/builtins/register/shadow_index_configurator.rb +53 -0
  57. data/lib/rggen/builtins/register/uniqueness_validator.rb +48 -0
  58. data/lib/rggen/builtins/register_block/apb.erb +27 -0
  59. data/lib/rggen/builtins/register_block/apb.rb +20 -0
  60. data/lib/rggen/builtins/register_block/base_address.rb +64 -0
  61. data/lib/rggen/builtins/register_block/block_model_constructor.rb +14 -0
  62. data/lib/rggen/builtins/register_block/block_model_default_map_creator.rb +39 -0
  63. data/lib/rggen/builtins/register_block/block_model_definition.rb +18 -0
  64. data/lib/rggen/builtins/register_block/byte_size.rb +37 -0
  65. data/lib/rggen/builtins/register_block/clock_reset.rb +8 -0
  66. data/lib/rggen/builtins/register_block/host_if.rb +46 -0
  67. data/lib/rggen/builtins/register_block/module_definition.rb +13 -0
  68. data/lib/rggen/builtins/register_block/name.rb +26 -0
  69. data/lib/rggen/builtins/register_block/ral_package_definition.rb +19 -0
  70. data/lib/rggen/builtins/register_block/reg_model_creator.rb +14 -0
  71. data/lib/rggen/builtins/register_block/reg_model_declarations.rb +7 -0
  72. data/lib/rggen/builtins/register_block/response_mux.erb +14 -0
  73. data/lib/rggen/builtins/register_block/response_mux.rb +16 -0
  74. data/lib/rggen/builtins/register_block/signal_declarations.rb +9 -0
  75. data/lib/rggen/builtins.rb +52 -0
  76. data/lib/rggen/commands.rb +23 -0
  77. data/lib/rggen/core_components/configuration/configuration_factory.rb +23 -0
  78. data/lib/rggen/core_components/configuration/item_factory.rb +13 -0
  79. data/lib/rggen/core_components/configuration/raise_error.rb +11 -0
  80. data/lib/rggen/core_components/configuration/setup.rb +14 -0
  81. data/lib/rggen/core_components/ral/item.rb +16 -0
  82. data/lib/rggen/core_components/ral/setup.rb +19 -0
  83. data/lib/rggen/core_components/register_map/bit_field_factory.rb +11 -0
  84. data/lib/rggen/core_components/register_map/component.rb +12 -0
  85. data/lib/rggen/core_components/register_map/generic_map.rb +69 -0
  86. data/lib/rggen/core_components/register_map/item.rb +22 -0
  87. data/lib/rggen/core_components/register_map/item_factory.rb +13 -0
  88. data/lib/rggen/core_components/register_map/loader.rb +13 -0
  89. data/lib/rggen/core_components/register_map/raise_error.rb +17 -0
  90. data/lib/rggen/core_components/register_map/register_block_factory.rb +29 -0
  91. data/lib/rggen/core_components/register_map/register_factory.rb +18 -0
  92. data/lib/rggen/core_components/register_map/register_map_factory.rb +21 -0
  93. data/lib/rggen/core_components/register_map/setup.rb +33 -0
  94. data/lib/rggen/core_components/rtl/component.rb +28 -0
  95. data/lib/rggen/core_components/rtl/item.rb +83 -0
  96. data/lib/rggen/core_components/rtl/setup.rb +19 -0
  97. data/lib/rggen/core_components.rb +23 -0
  98. data/lib/rggen/core_extensions/facets.rb +17 -0
  99. data/lib/rggen/core_extensions/forwardable.rb +26 -0
  100. data/lib/rggen/core_extensions/integer.rb +5 -0
  101. data/lib/rggen/core_extensions/math.rb +7 -0
  102. data/lib/rggen/exceptions.rb +22 -0
  103. data/lib/rggen/generator.rb +185 -0
  104. data/lib/rggen/input_base/component.rb +19 -0
  105. data/lib/rggen/input_base/component_factory.rb +58 -0
  106. data/lib/rggen/input_base/item.rb +170 -0
  107. data/lib/rggen/input_base/item_factory.rb +13 -0
  108. data/lib/rggen/input_base/loader.rb +14 -0
  109. data/lib/rggen/input_base/regexp_patterns.rb +29 -0
  110. data/lib/rggen/output_base/code_block.rb +72 -0
  111. data/lib/rggen/output_base/code_utility.rb +44 -0
  112. data/lib/rggen/output_base/component.rb +88 -0
  113. data/lib/rggen/output_base/component_factory.rb +32 -0
  114. data/lib/rggen/output_base/item.rb +175 -0
  115. data/lib/rggen/output_base/item_factory.rb +6 -0
  116. data/lib/rggen/output_base/line.rb +28 -0
  117. data/lib/rggen/output_base/template_utility.rb +29 -0
  118. data/lib/rggen/output_base/verilog_utility/class_definition.rb +23 -0
  119. data/lib/rggen/output_base/verilog_utility/declaration.rb +70 -0
  120. data/lib/rggen/output_base/verilog_utility/identifier.rb +29 -0
  121. data/lib/rggen/output_base/verilog_utility/module_definition.rb +47 -0
  122. data/lib/rggen/output_base/verilog_utility/package_definition.rb +67 -0
  123. data/lib/rggen/output_base/verilog_utility/structure_definition.rb +52 -0
  124. data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +43 -0
  125. data/lib/rggen/output_base/verilog_utility.rb +66 -0
  126. data/lib/rggen/version.rb +6 -0
  127. data/lib/rggen.rb +65 -0
  128. data/ral/compile.f +4 -0
  129. data/ral/rggen_ral_block.svh +84 -0
  130. data/ral/rggen_ral_field.svh +47 -0
  131. data/ral/rggen_ral_macros.svh +22 -0
  132. data/ral/rggen_ral_map.svh +124 -0
  133. data/ral/rggen_ral_pkg.sv +14 -0
  134. data/ral/rggen_ral_reg.svh +52 -0
  135. data/ral/rggen_ral_shadow_reg.svh +188 -0
  136. data/rggen.gemspec +45 -0
  137. data/rtl/bit_field/rggen_bit_field_rw.sv +28 -0
  138. data/rtl/register/rggen_address_decoder.sv +49 -0
  139. data/rtl/register_block/rggen_host_if_apb.sv +40 -0
  140. data/rtl/register_block/rggen_response_mux.sv +82 -0
  141. data/sample/sample.csv +14 -0
  142. data/sample/sample.json +4 -0
  143. data/sample/sample.xls +0 -0
  144. data/sample/sample.xlsx +0 -0
  145. data/sample/sample.yaml +2 -0
  146. data/sample/sample_0.sv +285 -0
  147. data/sample/sample_0_ral_pkg.sv +99 -0
  148. data/sample/sample_1.sv +172 -0
  149. data/sample/sample_1_ral_pkg.sv +53 -0
  150. data/sample/sample_setup.rb +21 -0
  151. data/setup/default.rb +11 -0
  152. metadata +296 -0
@@ -0,0 +1,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,8 @@
1
+ simple_item :register_block, :clock_reset do
2
+ rtl do
3
+ build do
4
+ input :clock, name: 'clk' , width: 1
5
+ input :reset, name: 'rst_n', width: 1
6
+ end
7
+ end
8
+ 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