rggen 0.3.0

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