rggen-verilog 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 (60) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +74 -0
  3. data/LICENSE +21 -0
  4. data/README.md +74 -0
  5. data/lib/rggen/verilog.rb +64 -0
  6. data/lib/rggen/verilog/bit_field/type.rb +85 -0
  7. data/lib/rggen/verilog/bit_field/type/rc_w0c_w1c_wc_woc.erb +21 -0
  8. data/lib/rggen/verilog/bit_field/type/rc_w0c_w1c_wc_woc.rb +40 -0
  9. data/lib/rggen/verilog/bit_field/type/reserved.erb +10 -0
  10. data/lib/rggen/verilog/bit_field/type/reserved.rb +7 -0
  11. data/lib/rggen/verilog/bit_field/type/ro.erb +11 -0
  12. data/lib/rggen/verilog/bit_field/type/ro.rb +21 -0
  13. data/lib/rggen/verilog/bit_field/type/rof.erb +11 -0
  14. data/lib/rggen/verilog/bit_field/type/rof.rb +7 -0
  15. data/lib/rggen/verilog/bit_field/type/rs_w0s_w1s_ws_wos.erb +19 -0
  16. data/lib/rggen/verilog/bit_field/type/rs_w0s_w1s_ws_wos.rb +31 -0
  17. data/lib/rggen/verilog/bit_field/type/rw_w1_wo_wo1.erb +16 -0
  18. data/lib/rggen/verilog/bit_field/type/rw_w1_wo_wo1.rb +23 -0
  19. data/lib/rggen/verilog/bit_field/type/rwc.erb +15 -0
  20. data/lib/rggen/verilog/bit_field/type/rwc.rb +24 -0
  21. data/lib/rggen/verilog/bit_field/type/rwe.erb +15 -0
  22. data/lib/rggen/verilog/bit_field/type/rwe.rb +24 -0
  23. data/lib/rggen/verilog/bit_field/type/rwl.erb +15 -0
  24. data/lib/rggen/verilog/bit_field/type/rwl.rb +24 -0
  25. data/lib/rggen/verilog/bit_field/type/rws.erb +16 -0
  26. data/lib/rggen/verilog/bit_field/type/rws.rb +27 -0
  27. data/lib/rggen/verilog/bit_field/type/w0crs_w1crs_wcrs.erb +15 -0
  28. data/lib/rggen/verilog/bit_field/type/w0crs_w1crs_wcrs.rb +20 -0
  29. data/lib/rggen/verilog/bit_field/type/w0src_w1src_wsrc.erb +15 -0
  30. data/lib/rggen/verilog/bit_field/type/w0src_w1src_wsrc.rb +20 -0
  31. data/lib/rggen/verilog/bit_field/type/w0t_w1t.erb +15 -0
  32. data/lib/rggen/verilog/bit_field/type/w0t_w1t.rb +19 -0
  33. data/lib/rggen/verilog/bit_field/type/w0trg_w1trg.erb +14 -0
  34. data/lib/rggen/verilog/bit_field/type/w0trg_w1trg.rb +19 -0
  35. data/lib/rggen/verilog/bit_field/type/wrc_wrs.erb +14 -0
  36. data/lib/rggen/verilog/bit_field/type/wrc_wrs.rb +13 -0
  37. data/lib/rggen/verilog/bit_field/verilog_top.rb +89 -0
  38. data/lib/rggen/verilog/component.rb +7 -0
  39. data/lib/rggen/verilog/factories.rb +11 -0
  40. data/lib/rggen/verilog/feature.rb +35 -0
  41. data/lib/rggen/verilog/register/type.rb +101 -0
  42. data/lib/rggen/verilog/register/type/default.erb +29 -0
  43. data/lib/rggen/verilog/register/type/external.erb +27 -0
  44. data/lib/rggen/verilog/register/type/external.rb +45 -0
  45. data/lib/rggen/verilog/register/type/indirect.erb +31 -0
  46. data/lib/rggen/verilog/register/type/indirect.rb +18 -0
  47. data/lib/rggen/verilog/register/verilog_top.rb +58 -0
  48. data/lib/rggen/verilog/register_block/protocol.rb +51 -0
  49. data/lib/rggen/verilog/register_block/protocol/apb.erb +33 -0
  50. data/lib/rggen/verilog/register_block/protocol/apb.rb +40 -0
  51. data/lib/rggen/verilog/register_block/protocol/axi4lite.erb +48 -0
  52. data/lib/rggen/verilog/register_block/protocol/axi4lite.rb +92 -0
  53. data/lib/rggen/verilog/register_block/verilog_macros.erb +4 -0
  54. data/lib/rggen/verilog/register_block/verilog_top.rb +104 -0
  55. data/lib/rggen/verilog/register_file/verilog_top.rb +30 -0
  56. data/lib/rggen/verilog/setup.rb +11 -0
  57. data/lib/rggen/verilog/utility.rb +13 -0
  58. data/lib/rggen/verilog/utility/local_scope.rb +15 -0
  59. data/lib/rggen/verilog/version.rb +7 -0
  60. metadata +133 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_feature(:register_block, :protocol) do
4
+ verilog do
5
+ shared_context.feature_registry(registry)
6
+
7
+ base_feature do
8
+ build do
9
+ parameter :address_width, {
10
+ name: 'ADDRESS_WIDTH', default: local_address_width
11
+ }
12
+ parameter :pre_decode, {
13
+ name: 'PRE_DECODE', default: 0
14
+ }
15
+ parameter :base_address, {
16
+ name: 'BASE_ADDRESS', width: address_width, default: 0
17
+ }
18
+ parameter :error_status, {
19
+ name: 'ERROR_STATUS', default: 0
20
+ }
21
+ parameter :default_read_data, {
22
+ name: 'DEFAULT_READ_DATA', width: bus_width, default: 0
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def bus_width
29
+ configuration.bus_width
30
+ end
31
+
32
+ def local_address_width
33
+ register_block.local_address_width
34
+ end
35
+
36
+ def total_registers
37
+ register_block.files_and_registers.sum(&:count)
38
+ end
39
+
40
+ def byte_size
41
+ register_block.byte_size
42
+ end
43
+ end
44
+
45
+ factory do
46
+ def target_feature_key(configuration, _register_block)
47
+ configuration.protocol
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ 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
+ ) u_adapter (
12
+ .i_clk (<%= register_block.clock %>),
13
+ .i_rst_n (<%= register_block.reset %>),
14
+ .i_psel (<%= psel %>),
15
+ .i_penable (<%= penable %>),
16
+ .i_paddr (<%= paddr %>),
17
+ .i_pprot (<%= pprot %>),
18
+ .i_pwrite (<%= pwrite %>),
19
+ .i_pstrb (<%= pstrb %>),
20
+ .i_pwdata (<%= pwdata %>),
21
+ .o_pready (<%= pready %>),
22
+ .o_prdata (<%= prdata %>),
23
+ .o_pslverr (<%= pslverr %>),
24
+ .o_register_valid (<%= register_block.register_valid %>),
25
+ .o_register_access (<%= register_block.register_access %>),
26
+ .o_register_address (<%= register_block.register_address %>),
27
+ .o_register_write_data (<%= register_block.register_write_data %>),
28
+ .o_register_strobe (<%= register_block.register_strobe %>),
29
+ .i_register_active (<%= register_block.register_active %>),
30
+ .i_register_ready (<%= register_block.register_ready %>),
31
+ .i_register_status (<%= register_block.register_status %>),
32
+ .i_register_read_data (<%= register_block.register_read_data %>)
33
+ );
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :apb) do
4
+ verilog do
5
+ build do
6
+ input :psel, {
7
+ name: 'i_psel', width: 1
8
+ }
9
+ input :penable, {
10
+ name: 'i_penable', width: 1
11
+ }
12
+ input :paddr, {
13
+ name: 'i_paddr', width: address_width
14
+ }
15
+ input :pprot, {
16
+ name: 'i_pprot', width: 3
17
+ }
18
+ input :pwrite, {
19
+ name: 'i_pwrite', width: 1
20
+ }
21
+ input :pstrb, {
22
+ name: 'i_pstrb', width: bus_width / 8
23
+ }
24
+ input :pwdata, {
25
+ name: 'i_pwdata', width: bus_width
26
+ }
27
+ output :pready, {
28
+ name: 'o_pready', width: 1
29
+ }
30
+ output :prdata, {
31
+ name: 'o_prdata', width: bus_width
32
+ }
33
+ output :pslverr, {
34
+ name: 'o_pslverr', width: 1
35
+ }
36
+ end
37
+
38
+ main_code :register_block, from_template: true
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ 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
+ .WRITE_FIRST (<%= write_first %>)
13
+ ) u_adapter (
14
+ .i_clk (<%= register_block.clock %>),
15
+ .i_rst_n (<%= register_block.reset %>),
16
+ .i_awvalid (<%= awvalid %>),
17
+ .o_awready (<%= awready %>),
18
+ .i_awid (<%= awid %>),
19
+ .i_awaddr (<%= awaddr %>),
20
+ .i_awprot (<%= awprot %>),
21
+ .i_wvalid (<%= wvalid %>),
22
+ .o_wready (<%= wready %>),
23
+ .i_wdata (<%= wdata %>),
24
+ .i_wstrb (<%= wstrb %>),
25
+ .o_bvalid (<%= bvalid %>),
26
+ .i_bready (<%= bready %>),
27
+ .o_bid (<%= bid %>),
28
+ .o_bresp (<%= bresp %>),
29
+ .i_arvalid (<%= arvalid %>),
30
+ .o_arready (<%= arready %>),
31
+ .i_arid (<%= arid %>),
32
+ .i_araddr (<%= araddr %>),
33
+ .i_arprot (<%= arprot %>),
34
+ .o_rvalid (<%= rvalid %>),
35
+ .i_rready (<%= rready %>),
36
+ .o_rid (<%= rid %>),
37
+ .o_rdata (<%= rdata %>),
38
+ .o_rresp (<%= rresp %>),
39
+ .o_register_valid (<%= register_block.register_valid %>),
40
+ .o_register_access (<%= register_block.register_access %>),
41
+ .o_register_address (<%= register_block.register_address %>),
42
+ .o_register_write_data (<%= register_block.register_write_data %>),
43
+ .o_register_strobe (<%= register_block.register_strobe %>),
44
+ .i_register_active (<%= register_block.register_active %>),
45
+ .i_register_ready (<%= register_block.register_ready %>),
46
+ .i_register_status (<%= register_block.register_status %>),
47
+ .i_register_read_data (<%= register_block.register_read_data %>)
48
+ );
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_list_item_feature(:register_block, :protocol, :axi4lite) do
4
+ verilog do
5
+ build do
6
+ parameter :id_width, {
7
+ name: 'ID_WIDTH', default: 0
8
+ }
9
+ parameter :write_first, {
10
+ name: 'WRITE_FIRST', default: 1
11
+ }
12
+
13
+ input :awvalid, {
14
+ name: 'i_awvalid', width: 1
15
+ }
16
+ output :awready, {
17
+ name: 'o_awready', width: 1
18
+ }
19
+ input :awid, {
20
+ name: 'i_awid', width: id_width_value
21
+ }
22
+ input :awaddr, {
23
+ name: 'i_awaddr', width: address_width
24
+ }
25
+ input :awprot, {
26
+ name: 'i_awprot', width: 3
27
+ }
28
+ input :wvalid, {
29
+ name: 'i_wvalid', width: 1
30
+ }
31
+ output :wready, {
32
+ name: 'o_wready', width: 1
33
+ }
34
+ input :wdata, {
35
+ name: 'i_wdata', width: bus_width
36
+ }
37
+ input :wstrb, {
38
+ name: 'i_wstrb', width: bus_width / 8
39
+ }
40
+ output :bvalid, {
41
+ name: 'o_bvalid', width: 1
42
+ }
43
+ input :bready, {
44
+ name: 'i_bready', width: 1
45
+ }
46
+ output :bid, {
47
+ name: 'o_bid', width: id_width_value
48
+ }
49
+ output :bresp, {
50
+ name: 'o_bresp', width: 2
51
+ }
52
+ input :arvalid, {
53
+ name: 'i_arvalid', width: 1
54
+ }
55
+ output :arready, {
56
+ name: 'o_arready', width: 1
57
+ }
58
+ input :arid, {
59
+ name: 'i_arid', width: id_width_value
60
+ }
61
+ input :araddr, {
62
+ name: 'i_araddr', width: address_width
63
+ }
64
+ input :arprot, {
65
+ name: 'i_arprot', width: 3
66
+ }
67
+ output :rvalid, {
68
+ name: 'o_rvalid', width: 1
69
+ }
70
+ input :rready, {
71
+ name: 'i_rready', width: 1
72
+ }
73
+ output :rid, {
74
+ name: 'o_rid', width: id_width_value
75
+ }
76
+ output :rdata, {
77
+ name: 'o_rdata', width: bus_width
78
+ }
79
+ output :rresp, {
80
+ name: 'o_rresp', width: 2
81
+ }
82
+ end
83
+
84
+ main_code :register_block, from_template: true
85
+
86
+ private
87
+
88
+ def id_width_value
89
+ "((#{id_width} == 0) ? 1 : #{id_width})"
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,4 @@
1
+ `ifndef rggen_slice
2
+ `define rggen_slice(EXPRESSION, WIDTH, INDEX) \
3
+ (((EXPRESSION) >> ((WIDTH) * (INDEX))) & {(WIDTH){1'b1}})
4
+ `endif
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_block, :verilog_top) do
4
+ verilog do
5
+ build do
6
+ input :clock, {
7
+ name: 'i_clk', width: 1
8
+ }
9
+ input :reset, {
10
+ name: 'i_rst_n', width: 1
11
+ }
12
+
13
+ wire :register_valid, {
14
+ name: 'w_register_valid', width: 1
15
+ }
16
+ wire :register_access, {
17
+ name: 'w_register_access', width: 2
18
+ }
19
+ wire :register_address, {
20
+ name: 'w_register_address', width: address_width
21
+ }
22
+ wire :register_write_data, {
23
+ name: 'w_register_write_data', width: bus_width
24
+ }
25
+ wire :register_strobe, {
26
+ name: 'w_register_strobe', width: bus_width / 8
27
+ }
28
+ wire :register_active, {
29
+ name: 'w_register_active', width: 1, array_size: [total_registers]
30
+ }
31
+ wire :register_ready, {
32
+ name: 'w_register_ready', width: 1, array_size: [total_registers]
33
+ }
34
+ wire :register_status, {
35
+ name: 'w_register_status', width: 2, array_size: [total_registers]
36
+ }
37
+ wire :register_read_data, {
38
+ name: 'w_register_read_data', width: bus_width, array_size: [total_registers]
39
+ }
40
+ wire :register_value, {
41
+ name: 'w_register_value', width: value_width, array_size: [total_registers]
42
+ }
43
+ end
44
+
45
+ write_file '<%= register_block.name %>.v' do |file|
46
+ file.body(&method(:body_code))
47
+ end
48
+
49
+ private
50
+
51
+ def total_registers
52
+ register_block.files_and_registers.sum(&:count)
53
+ end
54
+
55
+ def address_width
56
+ register_block.local_address_width
57
+ end
58
+
59
+ def bus_width
60
+ configuration.bus_width
61
+ end
62
+
63
+ def value_width
64
+ register_block.registers.map(&:width).max
65
+ end
66
+
67
+ def body_code(code)
68
+ macro_definition(code)
69
+ verilog_module_definition(code)
70
+ end
71
+
72
+ def macro_definition(code)
73
+ template_path = File.join(__dir__, 'verilog_macros.erb')
74
+ code << process_template(template_path)
75
+ end
76
+
77
+ def verilog_module_definition(code)
78
+ code << module_definition(register_block.name) do |verilog_module|
79
+ verilog_module.parameters parameters
80
+ verilog_module.ports ports
81
+ verilog_module.variables variables
82
+ verilog_module.body(&method(:verilog_module_body))
83
+ end
84
+ end
85
+
86
+ def parameters
87
+ register_block.declarations[:parameter]
88
+ end
89
+
90
+ def ports
91
+ register_block.declarations[:port]
92
+ end
93
+
94
+ def variables
95
+ register_block.declarations[:variable]
96
+ end
97
+
98
+ def verilog_module_body(code)
99
+ { register_block: nil, register_file: 1 }.each do |kind, depth|
100
+ register_block.generate_code(code, kind, :top_down, depth)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ RgGen.define_simple_feature(:register_file, :verilog_top) do
4
+ verilog do
5
+ include RgGen::SystemVerilog::RTL::RegisterIndex
6
+
7
+ main_code :register_file do
8
+ local_scope("g_#{register_file.name}") do |scope|
9
+ scope.top_scope top_scope?
10
+ scope.loop_size loop_size
11
+ scope.body(&method(:body_code))
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def top_scope?
18
+ register_file(:upper).nil?
19
+ end
20
+
21
+ def loop_size
22
+ (register_file.array? || nil) &&
23
+ local_loop_variables.zip(register_file.array_size).to_h
24
+ end
25
+
26
+ def body_code(code)
27
+ register_file.generate_code(code, :register_file, :top_down, 1)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rggen/verilog'
4
+ require 'rggen/systemverilog/rtl/setup'
5
+
6
+ RgGen.setup RgGen::Verilog do |builder|
7
+ builder.enable :register_block, [:verilog_top]
8
+ builder.enable :register_file, [:verilog_top]
9
+ builder.enable :register, [:verilog_top]
10
+ builder.enable :bit_field, [:verilog_top]
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Verilog
5
+ module Utility
6
+ private
7
+
8
+ def local_scope(name, attributes = {}, &block)
9
+ LocalScope.new(attributes.merge(name: name), &block).to_code
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Verilog
5
+ module Utility
6
+ class LocalScope < SystemVerilog::Common::Utility::LocalScope
7
+ private
8
+
9
+ def generate_for(genvar, size)
10
+ "for (#{genvar} = 0;#{genvar} < #{size};#{genvar} = #{genvar} + 1) begin : g"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end