rggen-verilog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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