rggen-veryl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +84 -0
  3. data/LICENSE +21 -0
  4. data/README.md +65 -0
  5. data/lib/rggen/veryl/bit_field/common.erb +8 -0
  6. data/lib/rggen/veryl/bit_field/type/custom.erb +25 -0
  7. data/lib/rggen/veryl/bit_field/type/custom.rb +121 -0
  8. data/lib/rggen/veryl/bit_field/type/rc_w0c_w1c_wc_woc.erb +21 -0
  9. data/lib/rggen/veryl/bit_field/type/rc_w0c_w1c_wc_woc.rb +46 -0
  10. data/lib/rggen/veryl/bit_field/type/ro_rotrg.erb +21 -0
  11. data/lib/rggen/veryl/bit_field/type/ro_rotrg.rb +40 -0
  12. data/lib/rggen/veryl/bit_field/type/rof.erb +20 -0
  13. data/lib/rggen/veryl/bit_field/type/rof.rb +7 -0
  14. data/lib/rggen/veryl/bit_field/type/rohw.erb +20 -0
  15. data/lib/rggen/veryl/bit_field/type/rohw.rb +28 -0
  16. data/lib/rggen/veryl/bit_field/type/row0trg_row1trg.erb +10 -0
  17. data/lib/rggen/veryl/bit_field/type/row0trg_row1trg.rb +30 -0
  18. data/lib/rggen/veryl/bit_field/type/rowo_rowotrg.erb +21 -0
  19. data/lib/rggen/veryl/bit_field/type/rowo_rowotrg.rb +52 -0
  20. data/lib/rggen/veryl/bit_field/type/rs_w0s_w1s_ws_wos.erb +21 -0
  21. data/lib/rggen/veryl/bit_field/type/rs_w0s_w1s_ws_wos.rb +36 -0
  22. data/lib/rggen/veryl/bit_field/type/rw_rwtrg_w1.erb +21 -0
  23. data/lib/rggen/veryl/bit_field/type/rw_rwtrg_w1.rb +46 -0
  24. data/lib/rggen/veryl/bit_field/type/rwc.erb +20 -0
  25. data/lib/rggen/veryl/bit_field/type/rwc.rb +26 -0
  26. data/lib/rggen/veryl/bit_field/type/rwe_rwl.erb +20 -0
  27. data/lib/rggen/veryl/bit_field/type/rwe_rwl.rb +34 -0
  28. data/lib/rggen/veryl/bit_field/type/rwhw.erb +19 -0
  29. data/lib/rggen/veryl/bit_field/type/rwhw.rb +30 -0
  30. data/lib/rggen/veryl/bit_field/type/rws.erb +20 -0
  31. data/lib/rggen/veryl/bit_field/type/rws.rb +26 -0
  32. data/lib/rggen/veryl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.erb +21 -0
  33. data/lib/rggen/veryl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.rb +35 -0
  34. data/lib/rggen/veryl/bit_field/type/w0t_w1t.erb +20 -0
  35. data/lib/rggen/veryl/bit_field/type/w0t_w1t.rb +23 -0
  36. data/lib/rggen/veryl/bit_field/type/w0trg_w1trg.erb +10 -0
  37. data/lib/rggen/veryl/bit_field/type/w0trg_w1trg.rb +20 -0
  38. data/lib/rggen/veryl/bit_field/type/wo_wo1_wotrg.erb +22 -0
  39. data/lib/rggen/veryl/bit_field/type/wo_wo1_wotrg.rb +38 -0
  40. data/lib/rggen/veryl/bit_field/type/wrc_wrs.erb +20 -0
  41. data/lib/rggen/veryl/bit_field/type/wrc_wrs.rb +20 -0
  42. data/lib/rggen/veryl/bit_field/type.rb +70 -0
  43. data/lib/rggen/veryl/bit_field/veryl_top.rb +102 -0
  44. data/lib/rggen/veryl/component.rb +8 -0
  45. data/lib/rggen/veryl/factories.rb +11 -0
  46. data/lib/rggen/veryl/feature.rb +46 -0
  47. data/lib/rggen/veryl/register/type/default.erb +15 -0
  48. data/lib/rggen/veryl/register/type/external.erb +13 -0
  49. data/lib/rggen/veryl/register/type/external.rb +28 -0
  50. data/lib/rggen/veryl/register/type/indirect.erb +17 -0
  51. data/lib/rggen/veryl/register/type/indirect.rb +22 -0
  52. data/lib/rggen/veryl/register/type/rw.erb +15 -0
  53. data/lib/rggen/veryl/register/type/rw.rb +7 -0
  54. data/lib/rggen/veryl/register/type.rb +34 -0
  55. data/lib/rggen/veryl/register/veryl_top.rb +43 -0
  56. data/lib/rggen/veryl/register_block/protocol/apb.erb +17 -0
  57. data/lib/rggen/veryl/register_block/protocol/apb.rb +14 -0
  58. data/lib/rggen/veryl/register_block/protocol/axi4lite.erb +19 -0
  59. data/lib/rggen/veryl/register_block/protocol/axi4lite.rb +20 -0
  60. data/lib/rggen/veryl/register_block/protocol/wishbone.erb +18 -0
  61. data/lib/rggen/veryl/register_block/protocol/wishbone.rb +17 -0
  62. data/lib/rggen/veryl/register_block/protocol.rb +54 -0
  63. data/lib/rggen/veryl/register_block/veryl_top.rb +71 -0
  64. data/lib/rggen/veryl/register_file/veryl_top.rb +26 -0
  65. data/lib/rggen/veryl/utility/data_object.rb +79 -0
  66. data/lib/rggen/veryl/utility/interface_instance.rb +43 -0
  67. data/lib/rggen/veryl/utility/local_scope.rb +48 -0
  68. data/lib/rggen/veryl/utility/modport.rb +29 -0
  69. data/lib/rggen/veryl/utility/module_definition.rb +63 -0
  70. data/lib/rggen/veryl/utility.rb +37 -0
  71. data/lib/rggen/veryl/version.rb +7 -0
  72. data/lib/rggen/veryl.rb +57 -0
  73. metadata +133 -0
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:bit_field, :veryl_top) do
4
+ veryl do
5
+ include RgGen::SystemVerilog::RTL::BitFieldIndex
6
+
7
+ build do
8
+ if bit_field.fixed_initial_value?
9
+ const :initial_value, {
10
+ name: initial_value_name, type: :bit, width: bit_field.width,
11
+ array_size: initial_value_size, default: initial_value_rhs
12
+ }
13
+ elsif bit_field.initial_value?
14
+ param :initial_value, {
15
+ name: initial_value_name, type: :bit, width: bit_field.width,
16
+ array_size: initial_value_size, default: initial_value_rhs
17
+ }
18
+ end
19
+
20
+ interface :bit_field_sub_if, {
21
+ name: 'bit_field_sub_if', interface_type: 'rggen::rggen_bit_field_if',
22
+ param_values: { WIDTH: bit_field.width },
23
+ variables: [
24
+ 'valid', 'read_mask', 'write_mask', 'write_data', 'read_data', 'value'
25
+ ]
26
+ }
27
+ end
28
+
29
+ main_code :register do
30
+ local_scope("g_#{bit_field.name}") do |s|
31
+ s.loop_size loop_size
32
+ s.consts consts
33
+ s.variables variables
34
+ s.body { |c| body_code(c) }
35
+ end
36
+ end
37
+
38
+ export def value(offsets = nil, width = nil)
39
+ value_lsb = bit_field.lsb(offsets&.last || local_index)
40
+ value_width = width || bit_field.width
41
+ register_if(offsets&.[](0..-2)).value[value_lsb, value_width]
42
+ end
43
+
44
+ private
45
+
46
+ def initial_value_name
47
+ if bit_field.fixed_initial_value?
48
+ 'INITIAL_VALUE'
49
+ else
50
+ "#{bit_field.full_name('_').upcase}_INITIAL_VALUE"
51
+ end
52
+ end
53
+
54
+ def initial_value_size
55
+ return unless bit_field.initial_value_array?
56
+
57
+ [bit_field.sequence_size]
58
+ end
59
+
60
+ def initial_value_rhs
61
+ if !bit_field.initial_value_array?
62
+ sized_initial_value
63
+ elsif bit_field.fixed_initial_value?
64
+ array(sized_initial_values)
65
+ else
66
+ repeat(bit_field.sequence_size, sized_initial_value)
67
+ end
68
+ end
69
+
70
+ def sized_initial_value
71
+ hex(bit_field.initial_value, bit_field.width)
72
+ end
73
+
74
+ def sized_initial_values
75
+ bit_field.initial_values.map { |v| hex(v, bit_field.width) }
76
+ end
77
+
78
+ def register_if(offsets)
79
+ index = register.index(offsets || register.local_indices)
80
+ register_block.register_if[index]
81
+ end
82
+
83
+ def loop_size
84
+ loop_variable = local_index
85
+ return unless loop_variable
86
+
87
+ { loop_variable => bit_field.sequence_size }
88
+ end
89
+
90
+ def consts
91
+ bit_field.declarations[:parameter]
92
+ end
93
+
94
+ def variables
95
+ bit_field.declarations[:variable]
96
+ end
97
+
98
+ def body_code(code)
99
+ bit_field.generate_code(code, :bit_field, :top_down)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Veryl
5
+ class Component < SystemVerilog::Common::Component
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Veryl
5
+ class ComponentFactory < Core::OutputBase::SourceFileComponentFactory
6
+ end
7
+
8
+ class FeatureFactory < Core::OutputBase::FeatureFactory
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Veryl
5
+ class Feature < SystemVerilog::Common::Feature
6
+ include Utility
7
+
8
+ private
9
+
10
+ def create_if_instance(_, attributes, &block)
11
+ InterfaceInstance.new(attributes, &block)
12
+ end
13
+
14
+ def create_port(direction, attributes, &block)
15
+ attributes =
16
+ { direction: direction }
17
+ .merge(attributes)
18
+ DataObject.new(:port, attributes, &block)
19
+ end
20
+
21
+ def create_modport(_, attributes, &block)
22
+ Modport.new(attributes, &block)
23
+ end
24
+
25
+ def create_param(_, attributes, &block)
26
+ DataObject.new(:param, attributes, &block)
27
+ end
28
+
29
+ def create_const(_, attributes, &block)
30
+ DataObject.new(:const, attributes, &block)
31
+ end
32
+
33
+ def create_var(_, attributes, &block)
34
+ DataObject.new(:var, attributes, &block)
35
+ end
36
+
37
+ define_entity :input, :create_port, :port, -> { register_block }
38
+ define_entity :output, :create_port, :port, -> { register_block }
39
+ define_entity :modport, :create_modport, :port, -> { register_block }
40
+ define_entity :interface, :create_if_instance, :variable, -> { component }
41
+ define_entity :param, :create_param, :parameter, -> { register_block }
42
+ define_entity :const, :create_const, :parameter, -> { component }
43
+ define_entity :var, :create_var, :variable, -> { component }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ inst u_register: rggen::rggen_default_register #(
2
+ READABLE: <%= readable %>,
3
+ WRITABLE: <%= writable %>,
4
+ ADDRESS_WIDTH: <%= address_width %>,
5
+ OFFSET_ADDRESS: <%= offset_address %>,
6
+ BUS_WIDTH: <%= bus_width %>,
7
+ DATA_WIDTH: <%= width %>,
8
+ VALUE_WIDTH: <%= value_width %>,
9
+ VALID_BITS: <%= valid_bits %>
10
+ )(
11
+ i_clk: <%= register_block.clock %>,
12
+ i_rst: <%= register_block.reset %>,
13
+ register_if: <%= register_if %>,
14
+ bit_field_if: <%= bit_field_if %>
15
+ );
@@ -0,0 +1,13 @@
1
+ inst u_register: rggen::rggen_external_register #(
2
+ ADDRESS_WIDTH: <%= address_width %>,
3
+ BUS_WIDTH: <%= bus_width %>,
4
+ VALUE_WIDTH: <%= value_width %>,
5
+ STROBE_WIDTH: <%= strobe_width %>,
6
+ START_ADDRESS: <%= start_address %>,
7
+ BYTE_SIZE: <%= byte_size %>
8
+ )(
9
+ i_clk: <%= register_block.clock %>,
10
+ i_rst: <%= register_block.reset %>,
11
+ register_if: <%= register_if %>,
12
+ bus_if: <%= bus_if %>
13
+ );
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :external) do
4
+ veryl do
5
+ build do
6
+ param :strobe_width, {
7
+ name: "#{register.name}_strobe_width".upcase,
8
+ type: :u32, default: configuration.byte_width
9
+ }
10
+ modport :bus_if, {
11
+ name: "#{register.name}_bus_if",
12
+ interface_type: 'rggen::rggen_bus_if', modport: 'master'
13
+ }
14
+ end
15
+
16
+ main_code :register, from_template: true
17
+
18
+ private
19
+
20
+ def start_address
21
+ hex(register.address_range.begin, address_width)
22
+ end
23
+
24
+ def byte_size
25
+ register.total_byte_size
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ inst u_register: rggen::rggen_indirect_register #(
2
+ READABLE: <%= readable %>,
3
+ WRITABLE: <%= writable %>,
4
+ ADDRESS_WIDTH: <%= address_width %>,
5
+ OFFSET_ADDRESS: <%= offset_address %>,
6
+ BUS_WIDTH: <%= bus_width %>,
7
+ DATA_WIDTH: <%= width %>,
8
+ VALUE_WIDTH: <%= value_width %>,
9
+ VALID_BITS: <%= valid_bits %>,
10
+ INDIRECT_MATCH_WIDTH: <%= index_match_width %>
11
+ )(
12
+ i_clk: <%= register_block.clock %>,
13
+ i_rst: <%= register_block.reset %>,
14
+ register_if: <%= register_if %>,
15
+ i_indirect_match: <%= indirect_match %>,
16
+ bit_field_if: <%= bit_field_if %>
17
+ );
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :indirect) do
4
+ veryl do
5
+ include RgGen::SystemVerilog::RTL::IndirectIndex
6
+
7
+ build do
8
+ var :indirect_match, { width: index_match_width }
9
+ end
10
+
11
+ main_code :register do |code|
12
+ indirect_index_matches(code)
13
+ code << process_template
14
+ end
15
+
16
+ private
17
+
18
+ def array_index_value(value, width)
19
+ width_cast(value, width)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ inst u_register: rggen::rggen_default_register #(
2
+ READABLE: 1,
3
+ WRITABLE: 1,
4
+ ADDRESS_WIDTH: <%= address_width %>,
5
+ OFFSET_ADDRESS: <%= offset_address %>,
6
+ BUS_WIDTH: <%= bus_width %>,
7
+ DATA_WIDTH: <%= width %>,
8
+ VALUE_WIDTH: <%= value_width %>,
9
+ VALID_BITS: <%= valid_bits %>
10
+ )(
11
+ i_clk: <%= register_block.clock %>,
12
+ i_rst: <%= register_block.reset %>,
13
+ register_if: <%= register_if %>,
14
+ bit_field_if: <%= bit_field_if %>
15
+ );
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :rw) do
4
+ veryl do
5
+ main_code :register, from_template: true
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_feature(:register, :type) do
4
+ veryl do
5
+ base_feature do
6
+ include RgGen::SystemVerilog::RTL::RegisterType
7
+
8
+ private
9
+
10
+ def register_if
11
+ register_block.register_if[register.index]
12
+ end
13
+
14
+ def bit_field_if
15
+ register.bit_field_if
16
+ end
17
+ end
18
+
19
+ default_feature do
20
+ template = File.join(__dir__, 'type', 'default.erb')
21
+ main_code :register, from_template: template
22
+ end
23
+
24
+ factory do
25
+ def target_feature_key(_configuration, register)
26
+ type = register.type
27
+ return type if [:default, *target_features.keys].any? { type == _1 }
28
+
29
+ error "code generator for #{type} register type " \
30
+ 'is not implemented'
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register, :veryl_top) do
4
+ veryl do
5
+ include RgGen::SystemVerilog::RTL::RegisterIndex
6
+
7
+ build do
8
+ unless register.bit_fields.empty?
9
+ interface :bit_field_if, {
10
+ name: 'bit_field_if', interface_type: 'rggen::rggen_bit_field_if',
11
+ param_values: { WIDTH: register.width },
12
+ variables: [
13
+ 'valid', 'read_mask', 'write_mask', 'write_data', 'read_data', 'value'
14
+ ]
15
+ }
16
+ end
17
+ end
18
+
19
+ main_code :register_file do
20
+ local_scope("g_#{register.name}") do |s|
21
+ s.loop_size loop_size
22
+ s.variables variables
23
+ s.body { |c| body_code(c) }
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def loop_size
30
+ return nil unless register.array?
31
+
32
+ local_loop_variables.zip(register.array_size).to_h
33
+ end
34
+
35
+ def variables
36
+ register.declarations[:variable]
37
+ end
38
+
39
+ def body_code(code)
40
+ register.generate_code(code, :register, :top_down)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ inst u_adapter: rggen::rggen_apb_adapter #(
2
+ ADDRESS_WIDTH: <%= address_width %>,
3
+ LOCAL_ADDRESS_WIDTH: <%= local_address_width %>,
4
+ BUS_WIDTH: <%= bus_width %>,
5
+ REGISTERS: <%= total_registers %>,
6
+ PRE_DECODE: <%= pre_decode %>,
7
+ BASE_ADDRESS: <%= base_address %>,
8
+ BYTE_SIZE: <%= byte_size %>,
9
+ ERROR_STATUS: <%= error_status %>,
10
+ DEFAULT_READ_DATA: <%= default_read_data %>,
11
+ INSERT_SLICER: <%= insert_slicer %>
12
+ )(
13
+ i_clk: <%= register_block.clock %>,
14
+ i_rst: <%= register_block.reset %>,
15
+ apb_if: <%= apb_if %>,
16
+ register_if: <%= register_block.register_if %>
17
+ );
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :apb) do
4
+ veryl do
5
+ build do
6
+ modport :apb_if, {
7
+ name: 'apb_if',
8
+ interface_type: 'rggen::rggen_apb_if', modport: 'slave'
9
+ }
10
+ end
11
+
12
+ main_code :register_block, from_template: true
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ inst u_adapter: rggen::rggen_axi4lite_adapter #(
2
+ ID_WIDTH: <%= id_width %>,
3
+ ADDRESS_WIDTH: <%= address_width %>,
4
+ LOCAL_ADDRESS_WIDTH: <%= local_address_width %>,
5
+ BUS_WIDTH: <%= bus_width %>,
6
+ REGISTERS: <%= total_registers %>,
7
+ PRE_DECODE: <%= pre_decode %>,
8
+ BASE_ADDRESS: <%= base_address %>,
9
+ BYTE_SIZE: <%= byte_size %>,
10
+ ERROR_STATUS: <%= error_status %>,
11
+ DEFAULT_READ_DATA: <%= default_read_data %>,
12
+ INSERT_SLICER: <%= insert_slicer %>,
13
+ WRITE_FIRST: <%= write_first %>
14
+ )(
15
+ i_clk: <%= register_block.clock %>,
16
+ i_rst: <%= register_block.reset %>,
17
+ axi4lite_if: <%= axi4lite_if %>,
18
+ register_if: <%= register_block.register_if %>
19
+ );
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :axi4lite) do
4
+ veryl do
5
+ build do
6
+ param :id_width, {
7
+ name: 'ID_WIDTH', type: :u32, default: 0
8
+ }
9
+ param :write_first, {
10
+ name: 'WRITE_FIRST', type: :bit, default: 1
11
+ }
12
+ modport :axi4lite_if, {
13
+ name: 'axi4lite_if',
14
+ interface_type: 'rggen::rggen_axi4lite_if', modport: 'slave'
15
+ }
16
+ end
17
+
18
+ main_code :register_block, from_template: true
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ inst u_adapter: rggen::rggen_wishbone_adapter #(
2
+ ADDRESS_WIDTH: <%= address_width %>,
3
+ LOCAL_ADDRESS_WIDTH: <%= local_address_width %>,
4
+ BUS_WIDTH: <%= bus_width %>,
5
+ REGISTERS: <%= total_registers %>,
6
+ PRE_DECODE: <%= pre_decode %>,
7
+ BASE_ADDRESS: <%= base_address %>,
8
+ BYTE_SIZE: <%= byte_size %>,
9
+ ERROR_STATUS: <%= error_status %>,
10
+ DEFAULT_READ_DATA: <%= default_read_data %>,
11
+ INSERT_SLICER: <%= insert_slicer %>,
12
+ USE_STALL: <%= use_stall %>
13
+ )(
14
+ i_clk: <%= register_block.clock %>,
15
+ i_rst: <%= register_block.reset %>,
16
+ wishbone_if: <%= wishbone_if %>,
17
+ register_if: <%= register_block.register_if %>
18
+ );
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :wishbone) do
4
+ veryl do
5
+ build do
6
+ param :use_stall, {
7
+ name: 'USE_STALL', type: :bit, default: 1
8
+ }
9
+ modport :wishbone_if, {
10
+ name: 'wishbone_if', interface_type:
11
+ 'rggen::rggen_wishbone_if', modport: 'slave'
12
+ }
13
+ end
14
+
15
+ main_code :register_block, from_template: true
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_feature(:register_block, :protocol) do
4
+ veryl do
5
+ shared_context.feature_registry(registry)
6
+
7
+ base_feature do
8
+ build do
9
+ param :address_width, {
10
+ name: 'ADDRESS_WIDTH', type: :u32, default: local_address_width
11
+ }
12
+ param :pre_decode, {
13
+ name: 'PRE_DECODE', type: :bit, default: 0
14
+ }
15
+ param :base_address, {
16
+ name: 'BASE_ADDRESS', type: :bit, width: address_width, default: all_bits_0
17
+ }
18
+ param :error_status, {
19
+ name: 'ERROR_STATUS', type: :bit, default: 0
20
+ }
21
+ param :default_read_data, {
22
+ name: 'DEFAULT_READ_DATA', type: :bit, width: bus_width, default: all_bits_0
23
+ }
24
+ param :insert_slicer, {
25
+ name: 'INSERT_SLICER', type: :bit, default: 0
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ def bus_width
32
+ configuration.bus_width
33
+ end
34
+
35
+ def local_address_width
36
+ register_block.local_address_width
37
+ end
38
+
39
+ def total_registers
40
+ register_block.files_and_registers.sum(&:count)
41
+ end
42
+
43
+ def byte_size
44
+ register_block.byte_size
45
+ end
46
+ end
47
+
48
+ factory do
49
+ def target_feature_key(configuration, _register_block)
50
+ configuration.protocol
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_block, :veryl_top) do
4
+ veryl do
5
+ build do
6
+ input :clock, { name: 'i_clk', type: :clock }
7
+ input :reset, { name: 'i_rst', type: :reset }
8
+
9
+ interface :register_if, {
10
+ name: 'register_if', interface_type: 'rggen::rggen_register_if',
11
+ param_values: param_values, array_size: [total_registers], variables: ['value']
12
+ }
13
+ end
14
+
15
+ export def value_width
16
+ register_block.registers.max_by(&:width)&.width
17
+ end
18
+
19
+ export def total_registers
20
+ register_block.files_and_registers.sum(&:count)
21
+ end
22
+
23
+ write_file '<%= register_block.name %>.veryl' do |f|
24
+ f.body do |code|
25
+ code << module_definition(register_block.name) do |m|
26
+ m.package_imports packages
27
+ m.params params
28
+ m.ports ports
29
+ m.variables variables
30
+ m.body { |c| body_code(c) }
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def param_values
38
+ { ADDRESS_WIDTH: address_width, BUS_WIDTH: bus_width, VALUE_WIDTH: value_width }
39
+ end
40
+
41
+ def address_width
42
+ register_block.local_address_width
43
+ end
44
+
45
+ def bus_width
46
+ configuration.bus_width
47
+ end
48
+
49
+ def packages
50
+ ['rggen::rggen_rtl_pkg', *register_block.package_imports(:register_block)]
51
+ end
52
+
53
+ def params
54
+ register_block.declarations[:parameter]
55
+ end
56
+
57
+ def ports
58
+ register_block.declarations[:port]
59
+ end
60
+
61
+ def variables
62
+ register_block.declarations[:variable]
63
+ end
64
+
65
+ def body_code(code)
66
+ { register_block: nil, register_file: 1 }.each do |kind, depth|
67
+ register_block.generate_code(code, kind, :top_down, depth)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_file, :veryl_top) do
4
+ veryl do
5
+ include RgGen::SystemVerilog::RTL::RegisterIndex
6
+
7
+ main_code :register_file do
8
+ local_scope("g_#{register_file.name}") do |s|
9
+ s.loop_size loop_size
10
+ s.body { |c| body_code(c) }
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def loop_size
17
+ return nil unless register_file.array?
18
+
19
+ local_loop_variables.zip(register_file.array_size).to_h
20
+ end
21
+
22
+ def body_code(code)
23
+ register_file.generate_code(code, :register_file, :top_down, 1)
24
+ end
25
+ end
26
+ end