rggen-veryl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE +21 -0
- data/README.md +65 -0
- data/lib/rggen/veryl/bit_field/common.erb +8 -0
- data/lib/rggen/veryl/bit_field/type/custom.erb +25 -0
- data/lib/rggen/veryl/bit_field/type/custom.rb +121 -0
- data/lib/rggen/veryl/bit_field/type/rc_w0c_w1c_wc_woc.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/rc_w0c_w1c_wc_woc.rb +46 -0
- data/lib/rggen/veryl/bit_field/type/ro_rotrg.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/ro_rotrg.rb +40 -0
- data/lib/rggen/veryl/bit_field/type/rof.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/rof.rb +7 -0
- data/lib/rggen/veryl/bit_field/type/rohw.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/rohw.rb +28 -0
- data/lib/rggen/veryl/bit_field/type/row0trg_row1trg.erb +10 -0
- data/lib/rggen/veryl/bit_field/type/row0trg_row1trg.rb +30 -0
- data/lib/rggen/veryl/bit_field/type/rowo_rowotrg.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/rowo_rowotrg.rb +52 -0
- data/lib/rggen/veryl/bit_field/type/rs_w0s_w1s_ws_wos.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/rs_w0s_w1s_ws_wos.rb +36 -0
- data/lib/rggen/veryl/bit_field/type/rw_rwtrg_w1.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/rw_rwtrg_w1.rb +46 -0
- data/lib/rggen/veryl/bit_field/type/rwc.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/rwc.rb +26 -0
- data/lib/rggen/veryl/bit_field/type/rwe_rwl.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/rwe_rwl.rb +34 -0
- data/lib/rggen/veryl/bit_field/type/rwhw.erb +19 -0
- data/lib/rggen/veryl/bit_field/type/rwhw.rb +30 -0
- data/lib/rggen/veryl/bit_field/type/rws.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/rws.rb +26 -0
- data/lib/rggen/veryl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.erb +21 -0
- data/lib/rggen/veryl/bit_field/type/w0crs_w0src_w1crs_w1src_wcrs_wsrc.rb +35 -0
- data/lib/rggen/veryl/bit_field/type/w0t_w1t.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/w0t_w1t.rb +23 -0
- data/lib/rggen/veryl/bit_field/type/w0trg_w1trg.erb +10 -0
- data/lib/rggen/veryl/bit_field/type/w0trg_w1trg.rb +20 -0
- data/lib/rggen/veryl/bit_field/type/wo_wo1_wotrg.erb +22 -0
- data/lib/rggen/veryl/bit_field/type/wo_wo1_wotrg.rb +38 -0
- data/lib/rggen/veryl/bit_field/type/wrc_wrs.erb +20 -0
- data/lib/rggen/veryl/bit_field/type/wrc_wrs.rb +20 -0
- data/lib/rggen/veryl/bit_field/type.rb +70 -0
- data/lib/rggen/veryl/bit_field/veryl_top.rb +102 -0
- data/lib/rggen/veryl/component.rb +8 -0
- data/lib/rggen/veryl/factories.rb +11 -0
- data/lib/rggen/veryl/feature.rb +46 -0
- data/lib/rggen/veryl/register/type/default.erb +15 -0
- data/lib/rggen/veryl/register/type/external.erb +13 -0
- data/lib/rggen/veryl/register/type/external.rb +28 -0
- data/lib/rggen/veryl/register/type/indirect.erb +17 -0
- data/lib/rggen/veryl/register/type/indirect.rb +22 -0
- data/lib/rggen/veryl/register/type/rw.erb +15 -0
- data/lib/rggen/veryl/register/type/rw.rb +7 -0
- data/lib/rggen/veryl/register/type.rb +34 -0
- data/lib/rggen/veryl/register/veryl_top.rb +43 -0
- data/lib/rggen/veryl/register_block/protocol/apb.erb +17 -0
- data/lib/rggen/veryl/register_block/protocol/apb.rb +14 -0
- data/lib/rggen/veryl/register_block/protocol/axi4lite.erb +19 -0
- data/lib/rggen/veryl/register_block/protocol/axi4lite.rb +20 -0
- data/lib/rggen/veryl/register_block/protocol/wishbone.erb +18 -0
- data/lib/rggen/veryl/register_block/protocol/wishbone.rb +17 -0
- data/lib/rggen/veryl/register_block/protocol.rb +54 -0
- data/lib/rggen/veryl/register_block/veryl_top.rb +71 -0
- data/lib/rggen/veryl/register_file/veryl_top.rb +26 -0
- data/lib/rggen/veryl/utility/data_object.rb +79 -0
- data/lib/rggen/veryl/utility/interface_instance.rb +43 -0
- data/lib/rggen/veryl/utility/local_scope.rb +48 -0
- data/lib/rggen/veryl/utility/modport.rb +29 -0
- data/lib/rggen/veryl/utility/module_definition.rb +63 -0
- data/lib/rggen/veryl/utility.rb +37 -0
- data/lib/rggen/veryl/version.rb +7 -0
- data/lib/rggen/veryl.rb +57 -0
- 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,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,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
|