rggen 0.10.0 → 0.11.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/rggen/built_in.rb +3 -2
  4. data/lib/rggen/built_in/bit_field/initial_value.rb +22 -0
  5. data/lib/rggen/built_in/bit_field/reference.rb +40 -1
  6. data/lib/rggen/built_in/bit_field/sv_rtl_top.rb +4 -2
  7. data/lib/rggen/built_in/bit_field/type.rb +44 -80
  8. data/lib/rggen/built_in/bit_field/type/rc_w0c_w1c.erb +4 -4
  9. data/lib/rggen/built_in/bit_field/type/rc_w0c_w1c.rb +11 -20
  10. data/lib/rggen/built_in/bit_field/type/reserved.erb +1 -1
  11. data/lib/rggen/built_in/bit_field/type/ro.erb +2 -2
  12. data/lib/rggen/built_in/bit_field/type/ro.rb +4 -7
  13. data/lib/rggen/built_in/bit_field/type/rof.erb +2 -2
  14. data/lib/rggen/built_in/bit_field/type/rof.rb +1 -1
  15. data/lib/rggen/built_in/bit_field/type/rs_w0s_w1s.erb +4 -4
  16. data/lib/rggen/built_in/bit_field/type/rs_w0s_w1s.rb +6 -12
  17. data/lib/rggen/built_in/bit_field/type/rw_wo.erb +3 -3
  18. data/lib/rggen/built_in/bit_field/type/rw_wo.rb +4 -7
  19. data/lib/rggen/built_in/bit_field/type/rwc_rwe_rwl.erb +16 -0
  20. data/lib/rggen/built_in/bit_field/type/rwc_rwe_rwl.rb +92 -0
  21. data/lib/rggen/built_in/bit_field/type/w0trg_w1trg.erb +9 -0
  22. data/lib/rggen/built_in/bit_field/type/w0trg_w1trg.rb +29 -0
  23. data/lib/rggen/built_in/register/type.rb +12 -0
  24. data/lib/rggen/built_in/register/type/default_sv_rtl.erb +3 -3
  25. data/lib/rggen/built_in/register/type/external.rb +9 -22
  26. data/lib/rggen/built_in/register/type/indirect.rb +1 -3
  27. data/lib/rggen/built_in/register/type/indirect_sv_rtl.erb +3 -3
  28. data/lib/rggen/built_in/register_block/protocol.rb +28 -0
  29. data/lib/rggen/built_in/register_block/protocol/apb.erb +4 -4
  30. data/lib/rggen/built_in/register_block/protocol/apb.rb +14 -38
  31. data/lib/rggen/built_in/register_block/protocol/axi4lite.erb +4 -4
  32. data/lib/rggen/built_in/register_block/protocol/axi4lite.rb +22 -64
  33. data/lib/rggen/built_in/register_block/sv_ral_package.rb +13 -6
  34. data/lib/rggen/built_in/register_block/sv_rtl_top.rb +8 -9
  35. data/lib/rggen/built_in/version.rb +1 -1
  36. data/lib/rggen/setup/default.rb +3 -2
  37. data/sample/block_0.rb +9 -4
  38. data/sample/block_0.sv +97 -20
  39. data/sample/block_0.xlsx +0 -0
  40. data/sample/block_0.yml +9 -4
  41. data/sample/block_0_ral_pkg.sv +16 -6
  42. metadata +11 -9
  43. data/lib/rggen/built_in/bit_field/type/rwe_rwl.erb +0 -14
  44. data/lib/rggen/built_in/bit_field/type/rwe_rwl.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e09995dab930b6561855eac179c962d2ff0fe1b27911fdbd1ee9a0afa960ea6
4
- data.tar.gz: cac78a33759860a229a043a6fc5f84d5bc7d451690308db6b2d11c035072eca5
3
+ metadata.gz: 279ed463e04f0bfee2ad6a615e321f93510d68141634390bfd8b032469a6aac4
4
+ data.tar.gz: b7305903d2a3fdb810b23dab382164bce94b80a214393ac2f725bd0f7387ebc2
5
5
  SHA512:
6
- metadata.gz: a629f19469e932d34e3ee0b8354d847535b516d3e132188b718ab7514fdd0648720e212cbe75f2a9ea69c9adad7f66759e806a5af1a11ce17644d0819a29a0fb
7
- data.tar.gz: 738543fc8968a66e0296f71ca26252a6046b51def7998da03815596a42092146d72e6f876f27d7669b7b6a432e6a094f51375bf45ce72851db8fc617491d3f91
6
+ metadata.gz: e200170be0b7da892f947569e7570d2fa26610f7236ba7d658812a2bba5f38fa3eeb6bce4d18ef669d4bfedacafe0466da712b708184b6104cae719b1abf99c0
7
+ data.tar.gz: a41037f504a60f39a71a87d677ce7177f5b8639d9da64acf98644986f5d3628a48afc2f2bbd821ef8ac23ccdd01087303e8ba2f819c4d41bd75248621b15c90f
data/README.md CHANGED
@@ -7,15 +7,15 @@
7
7
 
8
8
  # RgGen
9
9
 
10
- RgGen is a code generation tool for ASIC/IP/FPGA/RTL engineers. It will automatically generate soruce code related to control/status registers (CSR), e.g. SytemVerilog RTL, UVM RAL model, from human readable register map documents.
10
+ RgGen is a code generation tool for ASIC/IP/FPGA/RTL engineers. It will automatically generate soruce code related to control/status registers (CSR), e.g. SytemVerilog RTL, UVM RAL model, from human readable register map specifications.
11
11
 
12
12
  RgGen has following features:
13
13
 
14
- * Generate source files related to CSR from register map documents
14
+ * Generate source files related to CSR from register map specifications
15
15
  * Source files listed below will be generated:
16
16
  * SystemVerilog RTL
17
17
  * UVM RAL model
18
- * Register map documents can be written in human readable format
18
+ * Register map specifications can be written in human readable format
19
19
  * Supported formats are listed below:
20
20
  * Ruby with APIs to describe register map information
21
21
  * YAML
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rggen/systemverilog'
3
4
  require_relative 'built_in/version'
4
5
 
5
6
  module RgGen
@@ -36,8 +37,8 @@ module RgGen
36
37
  'built_in/bit_field/type/rof',
37
38
  'built_in/bit_field/type/rs_w0s_w1s',
38
39
  'built_in/bit_field/type/rw_wo',
39
- 'built_in/bit_field/type/rwe_rwl',
40
- 'built_in/bit_field/type/rwe_rwl'
40
+ 'built_in/bit_field/type/rwc_rwe_rwl',
41
+ 'built_in/bit_field/type/w0trg_w1trg'
41
42
  ].freeze
42
43
 
43
44
  def self.load_built_in
@@ -14,6 +14,11 @@ RgGen.define_simple_feature(:bit_field, :initial_value) do
14
14
  end
15
15
  end
16
16
 
17
+ verify(:component) do
18
+ error_condition { option[:require] && !initial_value? }
19
+ message { 'no initial value is given' }
20
+ end
21
+
17
22
  verify(:component) do
18
23
  error_condition { initial_value? && initial_value < min_initial_value }
19
24
  message do
@@ -32,8 +37,20 @@ RgGen.define_simple_feature(:bit_field, :initial_value) do
32
37
  end
33
38
  end
34
39
 
40
+ verify(:component) do
41
+ error_condition { initial_value? && !match_valid_condition? }
42
+ message do
43
+ "does not match the valid initial value condition: #{initial_value}"
44
+ end
45
+ end
46
+
35
47
  private
36
48
 
49
+ def option
50
+ @option ||=
51
+ (bit_field.options && bit_field.options[:initial_value]) || {}
52
+ end
53
+
37
54
  def min_initial_value
38
55
  bit_field.width == 1 ? 0 : -(2**(bit_field.width - 1))
39
56
  end
@@ -41,5 +58,10 @@ RgGen.define_simple_feature(:bit_field, :initial_value) do
41
58
  def max_initial_value
42
59
  2**bit_field.width - 1
43
60
  end
61
+
62
+ def match_valid_condition?
63
+ !option.key?(:valid_condition) ||
64
+ instance_exec(@initial_value, &option[:valid_condition])
65
+ end
44
66
  end
45
67
  end
@@ -3,7 +3,8 @@
3
3
  RgGen.define_simple_feature(:bit_field, :reference) do
4
4
  register_map do
5
5
  property :reference, forward_to: :reference_bit_field, verify: :all
6
- property :reference?, body: -> { !@input_reference.nil? }
6
+ property :reference?, body: -> { use_reference? && !no_reference? }
7
+ property :reference_width, forward_to: :required_width
7
8
  property :find_reference, forward_to: :find_reference_bit_field
8
9
 
9
10
  input_pattern /(#{variable_name})\.(#{variable_name})/
@@ -17,6 +18,11 @@ RgGen.define_simple_feature(:bit_field, :reference) do
17
18
  end
18
19
  end
19
20
 
21
+ verify(:component) do
22
+ error_condition { require_reference? && no_reference? }
23
+ message { 'no reference bit field is given' }
24
+ end
25
+
20
26
  verify(:component) do
21
27
  error_condition { reference? && @input_reference == bit_field.full_name }
22
28
  message { "self reference: #{@input_reference}" }
@@ -70,8 +76,33 @@ RgGen.define_simple_feature(:bit_field, :reference) do
70
76
  message { "refer to reserved bit field: #{@input_reference}" }
71
77
  end
72
78
 
79
+ verify(:all) do
80
+ error_condition { reference? && !match_width? }
81
+ message do
82
+ "#{required_width} bits reference bit field is required: " \
83
+ "#{reference_bit_field.width} bit(s) width"
84
+ end
85
+ end
86
+
73
87
  private
74
88
 
89
+ def option
90
+ @option ||=
91
+ (bit_field.options && bit_field.options[:reference]) || {}
92
+ end
93
+
94
+ def use_reference?
95
+ option.fetch(:use, false)
96
+ end
97
+
98
+ def require_reference?
99
+ use_reference? && option[:require]
100
+ end
101
+
102
+ def no_reference?
103
+ @input_reference.nil?
104
+ end
105
+
75
106
  def reference_bit_field
76
107
  (reference? || nil) &&
77
108
  (@reference_bit_field ||= lookup_reference)
@@ -96,5 +127,13 @@ RgGen.define_simple_feature(:bit_field, :reference) do
96
127
  !(bit_field.sequential? && reference_bit_field.sequential?) ||
97
128
  bit_field.sequence_size == reference_bit_field.sequence_size
98
129
  end
130
+
131
+ def required_width
132
+ option[:width] || bit_field.width
133
+ end
134
+
135
+ def match_width?
136
+ reference_bit_field.width >= required_width
137
+ end
99
138
  end
100
139
  end
@@ -47,10 +47,12 @@ RgGen.define_simple_feature(:bit_field, :sv_rtl_top) do
47
47
  [*register.array_size, bit_field.sequence_size].compact
48
48
  end
49
49
 
50
- def value(register_offset = nil, bit_field_offset = nil)
50
+ def value(register_offset = nil, bit_field_offset = nil, width = nil)
51
+ bit_field_offset ||= local_index
52
+ width ||= bit_field.width
51
53
  register_block
52
54
  .register_if[register.index(register_offset)]
53
- .value[bit_field.lsb(bit_field_offset || local_index), bit_field.width]
55
+ .value[bit_field.lsb(bit_field_offset), width]
54
56
  end
55
57
 
56
58
  private
@@ -33,28 +33,30 @@ RgGen.define_list_feature(:bit_field, :type) do
33
33
  end
34
34
 
35
35
  def volatile
36
- @volatile = true
36
+ @volatility = -> { true }
37
37
  end
38
38
 
39
39
  def non_volatile
40
- @volatile = false
40
+ @volatility = -> { false }
41
41
  end
42
42
 
43
- def volatile?
44
- @volatile.nil? || @volatile
43
+ def volatile?(&block)
44
+ @volatility = block
45
45
  end
46
46
 
47
- def need_initial_value(**options)
48
- @initial_value_options = options.merge(needed: true)
49
- end
47
+ attr_reader :volatility
50
48
 
51
- attr_reader :initial_value_options
49
+ def options
50
+ @options ||= {}
51
+ end
52
52
 
53
- def use_reference(**options)
54
- @reference_options = options.merge(usable: true)
53
+ def initial_value(**option)
54
+ options[:initial_value] = option
55
55
  end
56
56
 
57
- attr_reader :reference_options
57
+ def reference(**option)
58
+ options[:reference] = option
59
+ end
58
60
  end
59
61
 
60
62
  property :type
@@ -63,78 +65,19 @@ RgGen.define_list_feature(:bit_field, :type) do
63
65
  property :read_only?, body: -> { readable? && !writable? }
64
66
  property :write_only?, body: -> { writable? && !readable? }
65
67
  property :reserved?, body: -> { !(readable? || writable?) }
66
- property :volatile?, forward_to_helper: true
68
+ property :volatile?, forward_to: :volatility
69
+ property :options, forward_to_helper: true
67
70
 
68
71
  build { |value| @type = value }
69
72
 
70
- verify(:component) do
71
- error_condition { no_initial_value_given? }
72
- message { 'no initial value is given' }
73
- end
74
-
75
- verify(:component) do
76
- error_condition do
77
- bit_field.initial_value? && not_match_initial_value?
78
- end
79
- message do
80
- "value 0x#{required_initial_value.to_s(16)} is only allowed for " \
81
- "initial value: 0x#{bit_field.initial_value.to_s(16)}"
82
- end
83
- end
84
-
85
- verify(:component) do
86
- error_condition { no_reference_bit_field_given? }
87
- message { 'no reference bit field is given' }
88
- end
89
-
90
- verify(:all) do
91
- error_condition { invalid_reference_width? }
92
- message do
93
- "#{reference_width} bit(s) reference bit field is required: " \
94
- "#{bit_field.reference.full_name} " \
95
- "#{bit_field.reference.width} bit(s)"
96
- end
97
- end
98
-
99
73
  private
100
74
 
101
- def no_initial_value_given?
102
- helper.initial_value_options&.key?(:needed) &&
103
- !bit_field.initial_value?
104
- end
105
-
106
- def not_match_initial_value?
107
- helper.initial_value_options&.key?(:value) &&
108
- bit_field.initial_value != required_initial_value
109
- end
110
-
111
- def required_initial_value
112
- value = helper.initial_value_options[:value]
113
- if value.is_a?(Proc)
114
- instance_exec(&value)
115
- else
116
- value
75
+ def volatility
76
+ if @volatility.nil?
77
+ @volatility =
78
+ helper.volatility.nil? || instance_exec(&helper.volatility)
117
79
  end
118
- end
119
-
120
- def no_reference_bit_field_given?
121
- use_reference? &&
122
- helper.reference_options[:required] &&
123
- !bit_field.reference?
124
- end
125
-
126
- def invalid_reference_width?
127
- use_reference? &&
128
- bit_field.reference? &&
129
- bit_field.reference.width != reference_width
130
- end
131
-
132
- def use_reference?
133
- helper.reference_options&.key?(:usable)
134
- end
135
-
136
- def reference_width
137
- helper.reference_options[:width] || bit_field.width
80
+ @volatility
138
81
  end
139
82
  end
140
83
 
@@ -174,6 +117,14 @@ RgGen.define_list_feature(:bit_field, :type) do
174
117
  bit_field.full_name('_')
175
118
  end
176
119
 
120
+ def width
121
+ bit_field.width
122
+ end
123
+
124
+ def array_size
125
+ bit_field.array_size
126
+ end
127
+
177
128
  def initial_value
178
129
  hex(bit_field.initial_value, bit_field.width)
179
130
  end
@@ -184,9 +135,22 @@ RgGen.define_list_feature(:bit_field, :type) do
184
135
  end
185
136
 
186
137
  def reference_bit_field
187
- bit_field
188
- .find_reference(register_block.bit_fields)
189
- &.value(register.local_index, bit_field.local_index)
138
+ bit_field.reference? &&
139
+ bit_field
140
+ .find_reference(register_block.bit_fields)
141
+ .value(
142
+ register.local_index,
143
+ bit_field.local_index,
144
+ bit_field.reference_width
145
+ )
146
+ end
147
+
148
+ def bit_field_if
149
+ bit_field.bit_field_sub_if
150
+ end
151
+
152
+ def loop_variables
153
+ bit_field.loop_variables
190
154
  end
191
155
  end
192
156
 
@@ -2,14 +2,14 @@
2
2
  <% if [:w0c, :w1c].include?(bit_field.type) %>
3
3
  .CLEAR_VALUE (<%= clear_value %>),
4
4
  <% end %>
5
- .WIDTH (<%= bit_field.width %>),
5
+ .WIDTH (<%= width %>),
6
6
  .INITIAL_VALUE (<%= initial_value %>)
7
7
  ) u_bit_field (
8
8
  .i_clk (<%= register_block.clock %>),
9
9
  .i_rst_n (<%= register_block.reset%>),
10
- .bit_field_if (<%= bit_field.bit_field_sub_if %>),
11
- .i_set (<%= set[bit_field.loop_variables] %>),
10
+ .bit_field_if (<%= bit_field_if %>),
11
+ .i_set (<%= set[loop_variables] %>),
12
12
  .i_mask (<%= mask %>),
13
- .o_value (<%= value_out[bit_field.loop_variables] %>),
13
+ .o_value (<%= value_out[loop_variables] %>),
14
14
  .o_value_unmasked (<%= value_out_unmasked %>)
15
15
  );
@@ -3,16 +3,16 @@
3
3
  RgGen.define_list_item_feature(:bit_field, :type, :rc) do
4
4
  register_map do
5
5
  read_only
6
- use_reference
7
- need_initial_value
6
+ reference use: true
7
+ initial_value require: true
8
8
  end
9
9
  end
10
10
 
11
11
  RgGen.define_list_item_feature(:bit_field, :type, [:w0c, :w1c]) do
12
12
  register_map do
13
13
  read_write
14
- use_reference
15
- need_initial_value
14
+ reference use: true
15
+ initial_value require: true
16
16
  end
17
17
  end
18
18
 
@@ -20,26 +20,17 @@ RgGen.define_list_item_feature(:bit_field, :type, [:rc, :w0c, :w1c]) do
20
20
  sv_rtl do
21
21
  build do
22
22
  input :register_block, :set, {
23
- name: "i_#{full_name}_set",
24
- data_type: :logic,
25
- width: bit_field.width,
26
- array_size: bit_field.array_size,
27
- array_format: array_port_format
23
+ name: "i_#{full_name}_set", data_type: :logic, width: width,
24
+ array_size: array_size, array_format: array_port_format
28
25
  }
29
26
  output :register_block, :value_out, {
30
- name: "o_#{full_name}",
31
- data_type: :logic,
32
- width: bit_field.width,
33
- array_size: bit_field.array_size,
34
- array_format: array_port_format
27
+ name: "o_#{full_name}", data_type: :logic, width: width,
28
+ array_size: array_size, array_format: array_port_format
35
29
  }
36
30
  if bit_field.reference?
37
31
  output :register_block, :value_unmasked, {
38
- name: "o_#{full_name}_unmasked",
39
- data_type: :logic,
40
- width: bit_field.width,
41
- array_size: bit_field.array_size,
42
- array_format: array_port_format
32
+ name: "o_#{full_name}_unmasked", data_type: :logic, width: width,
33
+ array_size: array_size, array_format: array_port_format
43
34
  }
44
35
  end
45
36
  end
@@ -62,7 +53,7 @@ RgGen.define_list_item_feature(:bit_field, :type, [:rc, :w0c, :w1c]) do
62
53
 
63
54
  def value_out_unmasked
64
55
  (bit_field.reference? || nil) &&
65
- value_unmasked[bit_field.loop_variables]
56
+ value_unmasked[loop_variables]
66
57
  end
67
58
  end
68
59
  end
@@ -1,3 +1,3 @@
1
1
  rggen_bit_field_reserved u_bit_field (
2
- .bit_field_if (<%= bit_field.bit_field_sub_if %>)
2
+ .bit_field_if (<%= bit_field_if %>)
3
3
  );
@@ -1,6 +1,6 @@
1
1
  rggen_bit_field_ro #(
2
- .WIDTH (<%= bit_field.width %>)
2
+ .WIDTH (<%= width %>)
3
3
  ) u_bit_field (
4
- .bit_field_if (<%= bit_field.bit_field_sub_if %>),
4
+ .bit_field_if (<%= bit_field_if %>),
5
5
  .i_value (<%= reference_or_value_in %>)
6
6
  );
@@ -3,18 +3,15 @@
3
3
  RgGen.define_list_item_feature(:bit_field, :type, :ro) do
4
4
  register_map do
5
5
  read_only
6
- use_reference
6
+ reference use: true
7
7
  end
8
8
 
9
9
  sv_rtl do
10
10
  build do
11
11
  unless bit_field.reference?
12
12
  input :register_block, :value_in, {
13
- name: "i_#{full_name}",
14
- data_type: :logic,
15
- width: bit_field.width,
16
- array_size: bit_field.array_size,
17
- array_format: array_port_format
13
+ name: "i_#{full_name}", data_type: :logic, width: width,
14
+ array_size: array_size, array_format: array_port_format
18
15
  }
19
16
  end
20
17
  end
@@ -27,7 +24,7 @@ RgGen.define_list_item_feature(:bit_field, :type, :ro) do
27
24
  if bit_field.reference?
28
25
  reference_bit_field
29
26
  else
30
- value_in[bit_field.loop_variables]
27
+ value_in[loop_variables]
31
28
  end
32
29
  end
33
30
  end