rggen-vhdl 0.1.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 (57) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +84 -0
  3. data/LICENSE +21 -0
  4. data/README.md +74 -0
  5. data/lib/rggen/vhdl.rb +50 -0
  6. data/lib/rggen/vhdl/bit_field/type.rb +85 -0
  7. data/lib/rggen/vhdl/bit_field/type/rc_w0c_w1c_wc_woc.erb +27 -0
  8. data/lib/rggen/vhdl/bit_field/type/rc_w0c_w1c_wc_woc.rb +51 -0
  9. data/lib/rggen/vhdl/bit_field/type/ro.erb +24 -0
  10. data/lib/rggen/vhdl/bit_field/type/ro.rb +21 -0
  11. data/lib/rggen/vhdl/bit_field/type/rof.erb +24 -0
  12. data/lib/rggen/vhdl/bit_field/type/rof.rb +7 -0
  13. data/lib/rggen/vhdl/bit_field/type/rs_w0s_w1s_ws_wos.erb +27 -0
  14. data/lib/rggen/vhdl/bit_field/type/rs_w0s_w1s_ws_wos.rb +42 -0
  15. data/lib/rggen/vhdl/bit_field/type/rw_w1_wo_wo1.erb +26 -0
  16. data/lib/rggen/vhdl/bit_field/type/rw_w1_wo_wo1.rb +23 -0
  17. data/lib/rggen/vhdl/bit_field/type/rwc.erb +25 -0
  18. data/lib/rggen/vhdl/bit_field/type/rwc.rb +24 -0
  19. data/lib/rggen/vhdl/bit_field/type/rwe_rwl.erb +25 -0
  20. data/lib/rggen/vhdl/bit_field/type/rwe_rwl.rb +33 -0
  21. data/lib/rggen/vhdl/bit_field/type/rws.erb +24 -0
  22. data/lib/rggen/vhdl/bit_field/type/rws.rb +27 -0
  23. data/lib/rggen/vhdl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.erb +26 -0
  24. data/lib/rggen/vhdl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.rb +36 -0
  25. data/lib/rggen/vhdl/bit_field/type/w0t_w1t.erb +25 -0
  26. data/lib/rggen/vhdl/bit_field/type/w0t_w1t.rb +22 -0
  27. data/lib/rggen/vhdl/bit_field/type/w0trg_w1trg.erb +17 -0
  28. data/lib/rggen/vhdl/bit_field/type/w0trg_w1trg.rb +19 -0
  29. data/lib/rggen/vhdl/bit_field/type/wrc_wrs.erb +25 -0
  30. data/lib/rggen/vhdl/bit_field/type/wrc_wrs.rb +22 -0
  31. data/lib/rggen/vhdl/bit_field/vhdl_top.rb +93 -0
  32. data/lib/rggen/vhdl/component.rb +7 -0
  33. data/lib/rggen/vhdl/factories.rb +11 -0
  34. data/lib/rggen/vhdl/feature.rb +31 -0
  35. data/lib/rggen/vhdl/register/default.erb +29 -0
  36. data/lib/rggen/vhdl/register/type.rb +109 -0
  37. data/lib/rggen/vhdl/register/type/default.erb +31 -0
  38. data/lib/rggen/vhdl/register/type/external.erb +29 -0
  39. data/lib/rggen/vhdl/register/type/external.rb +44 -0
  40. data/lib/rggen/vhdl/register/type/indirect.erb +35 -0
  41. data/lib/rggen/vhdl/register/type/indirect.rb +34 -0
  42. data/lib/rggen/vhdl/register/vhdl_top.rb +40 -0
  43. data/lib/rggen/vhdl/register_block/protocol.rb +48 -0
  44. data/lib/rggen/vhdl/register_block/protocol/apb.erb +34 -0
  45. data/lib/rggen/vhdl/register_block/protocol/apb.rb +20 -0
  46. data/lib/rggen/vhdl/register_block/protocol/axi4lite.erb +49 -0
  47. data/lib/rggen/vhdl/register_block/protocol/axi4lite.rb +42 -0
  48. data/lib/rggen/vhdl/register_block/vhdl_top.erb +26 -0
  49. data/lib/rggen/vhdl/register_block/vhdl_top.rb +103 -0
  50. data/lib/rggen/vhdl/register_file/vhdl_top.rb +25 -0
  51. data/lib/rggen/vhdl/setup.rb +11 -0
  52. data/lib/rggen/vhdl/utility.rb +28 -0
  53. data/lib/rggen/vhdl/utility/data_object.rb +91 -0
  54. data/lib/rggen/vhdl/utility/identifier.rb +38 -0
  55. data/lib/rggen/vhdl/utility/local_scope.rb +66 -0
  56. data/lib/rggen/vhdl/version.rb +7 -0
  57. metadata +130 -0
@@ -0,0 +1,35 @@
1
+ <% index_fields_and_values.each_with_index do |(field, value), i| %>
2
+ <%= indirect_match[i] %> <= '1' when unsigned(<%= field %>) = <%= value %> else '0';
3
+ <% end %>
4
+ u_register: entity work.rggen_indirect_register
5
+ generic map (
6
+ READABLE => <%= readable? %>,
7
+ WRITABLE => <%= writable? %>,
8
+ ADDRESS_WIDTH => <%= address_width %>,
9
+ OFFSET_ADDRESS => <%= offset_address %>,
10
+ BUS_WIDTH => <%= bus_width %>,
11
+ DATA_WIDTH => <%= width %>,
12
+ VALID_BITS => <%= valid_bits %>,
13
+ INDIRECT_MATCH_WIDTH => <%= match_width %>
14
+ )
15
+ port map (
16
+ i_clk => <%= clock %>,
17
+ i_rst_n => <%= reset %>,
18
+ i_register_valid => <%= register_valid %>,
19
+ i_register_access => <%= register_access %>,
20
+ i_register_address => <%= register_address %>,
21
+ i_register_write_data => <%= register_write_data %>,
22
+ i_register_strobe => <%= register_strobe %>,
23
+ o_register_active => <%= register_active %>,
24
+ o_register_ready => <%= register_ready %>,
25
+ o_register_status => <%= register_status %>,
26
+ o_register_read_data => <%= register_read_data %>,
27
+ o_register_value => <%= register_value %>,
28
+ i_indirect_match => <%= indirect_match %>,
29
+ o_bit_field_valid => <%= bit_field_valid %>,
30
+ o_bit_field_read_mask => <%= bit_field_read_mask %>,
31
+ o_bit_field_write_mask => <%= bit_field_write_mask %>,
32
+ o_bit_field_write_data => <%= bit_field_write_data %>,
33
+ i_bit_field_read_data => <%= bit_field_read_data %>,
34
+ i_bit_field_value => <%= bit_field_value %>
35
+ );
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register, :type, :indirect) do
4
+ vhdl do
5
+ build do
6
+ signal :indirect_match, { width: match_width }
7
+ end
8
+
9
+ main_code :register, from_template: true
10
+
11
+ private
12
+
13
+ def match_width
14
+ register.index_entries.size
15
+ end
16
+
17
+ def index_fields
18
+ register
19
+ .collect_index_fields(register_block.bit_fields)
20
+ .map(&:value)
21
+ end
22
+
23
+ def index_values
24
+ loop_variables = register.local_loop_variables
25
+ register.index_entries.map do |entry|
26
+ entry.array_index? && loop_variables.shift || entry.value
27
+ end
28
+ end
29
+
30
+ def index_fields_and_values
31
+ index_fields.zip(index_values)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register, :vhdl_top) do
4
+ vhdl do
5
+ include RgGen::SystemVerilog::RTL::RegisterIndex
6
+
7
+ build do
8
+ unless register.bit_fields.empty?
9
+ signal :bit_field_valid
10
+ signal :bit_field_read_mask, width: register.width
11
+ signal :bit_field_write_mask, width: register.width
12
+ signal :bit_field_write_data, width: register.width
13
+ signal :bit_field_read_data, width: register.width
14
+ signal :bit_field_value, width: register.width
15
+ end
16
+ end
17
+
18
+ main_code :register_file do
19
+ local_scope("g_#{register.name}") do |scope|
20
+ scope.loop_size loop_size
21
+ scope.signals signals
22
+ scope.body(&method(:body_code))
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def loop_size
29
+ register.array? && local_loop_variables.zip(register.array_size) || nil
30
+ end
31
+
32
+ def signals
33
+ register.declarations[:signal]
34
+ end
35
+
36
+ def body_code(code)
37
+ register.generate_code(code, :register, :top_down)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_feature(:register_block, :protocol) do
4
+ vhdl do
5
+ shared_context.feature_registry(registry)
6
+
7
+ base_feature do
8
+ build do
9
+ generic :address_width, {
10
+ name: 'ADDRESS_WIDTH', type: :positive, default: local_address_width
11
+ }
12
+ generic :pre_decode, {
13
+ name: 'PRE_DECODE', type: :boolean, default: false
14
+ }
15
+ generic :base_address, {
16
+ name: 'BASE_ADDRESS', default: hex(0, 4)
17
+ }
18
+ generic :error_status, {
19
+ name: 'ERROR_STATUS', type: :boolean, default: false
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def bus_width
26
+ configuration.bus_width
27
+ end
28
+
29
+ def local_address_width
30
+ register_block.local_address_width
31
+ end
32
+
33
+ def total_registers
34
+ register_block.files_and_registers.sum(&:count)
35
+ end
36
+
37
+ def byte_size
38
+ register_block.byte_size
39
+ end
40
+ end
41
+
42
+ factory do
43
+ def target_feature_key(configuration, _register_block)
44
+ configuration.protocol
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ u_adapter: entity work.rggen_apb_adaper
2
+ generic map (
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
+ )
12
+ port map (
13
+ i_clk => <%= register_block.clock %>,
14
+ i_rst_n => <%= register_block.reset %>,
15
+ i_psel => <%= psel %>,
16
+ i_penable => <%= penable %>,
17
+ i_paddr => <%= paddr %>,
18
+ i_pprot => <%= pprot %>,
19
+ i_pwrite => <%= pwrite %>,
20
+ i_pstrb => <%= pstrb %>,
21
+ i_pwdata => <%= pwdata %>,
22
+ o_pready => <%= pready %>,
23
+ o_prdata => <%= prdata %>,
24
+ o_pslverr => <%= pslverr %>,
25
+ o_register_valid => <%= register_block.register_valid %>,
26
+ o_register_access => <%= register_block.register_access %>,
27
+ o_register_address => <%= register_block.register_address %>,
28
+ o_register_write_data => <%= register_block.register_write_data %>,
29
+ o_register_strobe => <%= register_block.register_strobe %>,
30
+ i_register_active => <%= register_block.register_active %>,
31
+ i_register_ready => <%= register_block.register_ready %>,
32
+ i_register_status => <%= register_block.register_status %>,
33
+ i_register_read_data => <%= register_block.register_read_data %>
34
+ );
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :apb) do
4
+ vhdl do
5
+ build do
6
+ input :psel, { name: 'i_psel' }
7
+ input :penable, { name: 'i_penable' }
8
+ input :paddr, { name: 'i_paddr', width: address_width }
9
+ input :pprot, { name: 'i_pprot', width: 3 }
10
+ input :pwrite, { name: 'i_pwrite' }
11
+ input :pstrb, { name: 'i_pstrb', width: bus_width / 8 }
12
+ input :pwdata, { name: 'i_pwdata', width: bus_width }
13
+ output :pready, { name: 'o_pready' }
14
+ output :prdata, { name: 'o_prdata', width: bus_width }
15
+ output :pslverr, { name: 'o_pslverr' }
16
+ end
17
+
18
+ main_code :register_block, from_template: true
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ u_adapter: entity work.rggen_axi4lite_adapter
2
+ generic map (
3
+ ID_WIDTH => <%= id_width %>,
4
+ ADDRESS_WIDTH => <%= address_width %>,
5
+ LOCAL_ADDRESS_WIDTH => <%= local_address_width %>,
6
+ BUS_WIDTH => <%= bus_width %>,
7
+ REGISTERS => <%= total_registers %>,
8
+ PRE_DECODE => <%= pre_decode %>,
9
+ BASE_ADDRESS => <%= base_address %>,
10
+ BYTE_SIZE => <%= byte_size %>,
11
+ ERROR_STATUS => <%= error_status %>,
12
+ WRITE_FIRST => <%= write_first %>
13
+ )
14
+ port map (
15
+ i_clk => <%= register_block.clock %>,
16
+ i_rst_n => <%= register_block.reset %>,
17
+ i_awvalid => <%= awvalid %>,
18
+ o_awready => <%= awready %>,
19
+ i_awid => <%= awid %>,
20
+ i_awaddr => <%= awaddr %>,
21
+ i_awprot => <%= awprot %>,
22
+ i_wvalid => <%= wvalid %>,
23
+ o_wready => <%= wready %>,
24
+ i_wdata => <%= wdata %>,
25
+ i_wstrb => <%= wstrb %>,
26
+ o_bvalid => <%= bvalid %>,
27
+ i_bready => <%= bready %>,
28
+ o_bid => <%= bid %>,
29
+ o_bresp => <%= bresp %>,
30
+ i_arvalid => <%= arvalid %>,
31
+ o_arready => <%= arready %>,
32
+ i_arid => <%= arid %>,
33
+ i_araddr => <%= araddr %>,
34
+ i_arprot => <%= arprot %>,
35
+ o_rvalid => <%= rvalid %>,
36
+ i_rready => <%= rready %>,
37
+ o_rid => <%= rid %>,
38
+ o_rdata => <%= rdata %>,
39
+ o_rresp => <%= rresp %>,
40
+ o_register_valid => <%= register_block.register_valid %>,
41
+ o_register_access => <%= register_block.register_access %>,
42
+ o_register_address => <%= register_block.register_address %>,
43
+ o_register_write_data => <%= register_block.register_write_data %>,
44
+ o_register_strobe => <%= register_block.register_strobe %>,
45
+ i_register_active => <%= register_block.register_active %>,
46
+ i_register_ready => <%= register_block.register_ready %>,
47
+ i_register_status => <%= register_block.register_status %>,
48
+ i_register_read_data => <%= register_block.register_read_data %>
49
+ );
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :axi4lite) do
4
+ vhdl do
5
+ build do
6
+ generic :id_width, { name: 'ID_WIDTH', type: :natural, default: 0 }
7
+ generic :write_first, { name: 'WRITE_FIRST', type: :boolean, default: true }
8
+
9
+ input :awvalid, { name: 'i_awvalid' }
10
+ output :awready, { name: 'o_awready' }
11
+ input :awid, { name: 'i_awid', width: id_width_value }
12
+ input :awaddr, { name: 'i_awaddr', width: address_width }
13
+ input :awprot, { name: 'i_awprot', width: 3 }
14
+ input :wvalid, { name: 'i_wvalid' }
15
+ output :wready, { name: 'o_wready' }
16
+ input :wdata, { name: 'i_wdata', width: bus_width }
17
+ input :wstrb, { name: 'i_wstrb', width: bus_width / 8 }
18
+ output :bvalid, { name: 'o_bvalid' }
19
+ input :bready, { name: 'i_bready' }
20
+ output :bid, { name: 'o_bid', width: id_width_value }
21
+ output :bresp, { name: 'o_bresp', width: 2 }
22
+ input :arvalid, { name: 'i_arvalid' }
23
+ output :arready, { name: 'o_arready' }
24
+ input :arid, { name: 'i_arid', width: id_width_value }
25
+ input :araddr, { name: 'i_araddr', width: address_width }
26
+ input :arprot, { name: 'i_arprot', width: 3 }
27
+ output :rvalid, { name: 'o_rvalid' }
28
+ input :rready, { name: 'i_rready' }
29
+ output :rid, { name: 'o_rid', width: id_width_value }
30
+ output :rdata, { name: 'o_rdata', width: bus_width }
31
+ output :rresp, { name: 'o_rresp', width: 2 }
32
+ end
33
+
34
+ main_code :register_block, from_template: true
35
+
36
+ private
37
+
38
+ def id_width_value
39
+ "clip_id_width(#{id_width})"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ library ieee;
2
+ use ieee.std_logic_1164.all;
3
+ use ieee.numeric_std.all;
4
+
5
+ use work.rggen_rtl.all;
6
+
7
+ entity <%= register_block.name %> is
8
+ generic (
9
+ <% generic_declarations.each do |declaration| %>
10
+ <%= declaration %>
11
+ <% end %>
12
+ );
13
+ port (
14
+ <% port_declarations.each do |declaration| %>
15
+ <%= declaration %>
16
+ <% end %>
17
+ );
18
+ end <%= register_block.name %>;
19
+
20
+ architecture rtl of <%= register_block.name %> is
21
+ <% signal_declarations.each do |declaration| %>
22
+ <%= declaration %>;
23
+ <% end %>
24
+ begin
25
+ <%= architecture_body_code.to_s.chomp %>
26
+ end rtl;
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_block, :vhdl_top) do
4
+ vhdl do
5
+ build do
6
+ input :clock, { name: 'i_clk' }
7
+ input :reset, { name: 'i_rst_n' }
8
+
9
+ signal :register_valid
10
+ signal :register_access, {
11
+ width: 2
12
+ }
13
+ signal :register_address, {
14
+ width: address_width
15
+ }
16
+ signal :register_write_data, {
17
+ width: bus_width
18
+ }
19
+ signal :register_strobe, {
20
+ width: bus_width / 8
21
+ }
22
+ signal :register_active, {
23
+ array_size: [total_registers]
24
+ }
25
+ signal :register_ready, {
26
+ array_size: [total_registers]
27
+ }
28
+ signal :register_status, {
29
+ width: 2, array_size: [total_registers]
30
+ }
31
+ signal :register_read_data, {
32
+ width: bus_width, array_size: [total_registers]
33
+ }
34
+ signal :register_value, {
35
+ width: value_width, array_size: [total_registers]
36
+ }
37
+ end
38
+
39
+ write_file '<%= register_block.name %>.vhd' do |file|
40
+ file.body { process_template }
41
+ end
42
+
43
+ private
44
+
45
+ def total_registers
46
+ register_block.files_and_registers.sum(&:count)
47
+ end
48
+
49
+ def address_width
50
+ register_block.local_address_width
51
+ end
52
+
53
+ def bus_width
54
+ configuration.bus_width
55
+ end
56
+
57
+ def value_width
58
+ register_block.registers.map(&:width).max
59
+ end
60
+
61
+ def generic_declarations
62
+ register_block
63
+ .declarations[:generic]
64
+ .yield_self(&method(:add_terminator))
65
+ end
66
+
67
+ def port_declarations
68
+ register_block
69
+ .declarations[:port]
70
+ .yield_self(&method(:sort_port_declarations))
71
+ .yield_self(&method(:add_terminator))
72
+ end
73
+
74
+ def signal_declarations
75
+ register_block.declarations[:signal]
76
+ end
77
+
78
+ def architecture_body_code
79
+ code_block(2) do |code|
80
+ register_block.generate_code(code, :register_block, :top_down)
81
+ register_block.generate_code(code, :register_file, :top_down, 1)
82
+ end
83
+ end
84
+
85
+ def sort_port_declarations(declarations)
86
+ declarations
87
+ .partition(&method(:clock_or_reset?))
88
+ .flatten
89
+ end
90
+
91
+ def clock_or_reset?(declaration)
92
+ [clock.to_s, reset.to_s]
93
+ .any? { |port_name| declaration.include?(port_name) }
94
+ end
95
+
96
+ def add_terminator(declarations)
97
+ declarations.map.with_index do |declaration, i|
98
+ (i == declarations.size - 1) && declaration ||
99
+ declaration + semicolon
100
+ end
101
+ end
102
+ end
103
+ end