systemrdl 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +32 -2
- data/lib/systemrdl/evaluator/address_allocation.rb +37 -20
- data/lib/systemrdl/evaluator/address_operation.rb +1 -1
- data/lib/systemrdl/evaluator/addrmap.rb +18 -9
- data/lib/systemrdl/evaluator/array_component.rb +30 -2
- data/lib/systemrdl/evaluator/block_component.rb +42 -0
- data/lib/systemrdl/evaluator/builtin_properties.rb +66 -1
- data/lib/systemrdl/evaluator/component_definition.rb +21 -18
- data/lib/systemrdl/evaluator/component_insts.rb +43 -4
- data/lib/systemrdl/evaluator/field.rb +39 -25
- data/lib/systemrdl/evaluator/inst_type_aware_component.rb +17 -0
- data/lib/systemrdl/evaluator/instance.rb +21 -27
- data/lib/systemrdl/evaluator/mem.rb +190 -0
- data/lib/systemrdl/evaluator/processor.rb +11 -0
- data/lib/systemrdl/evaluator/property.rb +17 -6
- data/lib/systemrdl/evaluator/reg.rb +107 -9
- data/lib/systemrdl/evaluator/regfile.rb +21 -1
- data/lib/systemrdl/evaluator/root.rb +1 -1
- data/lib/systemrdl/model/instance.rb +83 -50
- data/lib/systemrdl/model/value.rb +27 -3
- data/lib/systemrdl/model.rb +39 -3
- data/lib/systemrdl/version.rb +1 -1
- data/lib/systemrdl.rb +3 -0
- metadata +4 -1
|
@@ -25,9 +25,7 @@ module SystemRDL
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def upper_layers(include_self: false)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
layers = [*component.upper_layers, component]
|
|
28
|
+
layers = (layer == :root && []) || component.upper_layers(include_self: true)
|
|
31
29
|
layers << self if include_self
|
|
32
30
|
layers
|
|
33
31
|
end
|
|
@@ -37,12 +35,9 @@ module SystemRDL
|
|
|
37
35
|
@insts&.evaluate(instance, @parent, @id, **optargs)
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
def create_instances(parent_instance,
|
|
41
|
-
eval_array(
|
|
42
|
-
create_instance(
|
|
43
|
-
parent_instance, inst_name, inst_values,
|
|
44
|
-
array_info, token_range, **optargs
|
|
45
|
-
)
|
|
38
|
+
def create_instances(parent_instance, inst_args, token_range, **optargs)
|
|
39
|
+
eval_array(inst_args.values) do |array_info|
|
|
40
|
+
create_instance(parent_instance, inst_args, array_info, token_range, **optargs)
|
|
46
41
|
end
|
|
47
42
|
end
|
|
48
43
|
|
|
@@ -93,8 +88,8 @@ module SystemRDL
|
|
|
93
88
|
def check_property_exclusivity(instance, names)
|
|
94
89
|
properties =
|
|
95
90
|
names
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
.map { |name| instance.property_value(name) }
|
|
92
|
+
.select { |v| v&.value }
|
|
98
93
|
return if properties.size <= 1
|
|
99
94
|
|
|
100
95
|
labels = [names[..-2].join(', '), names[-1]].join(' and ')
|
|
@@ -114,17 +109,19 @@ module SystemRDL
|
|
|
114
109
|
yield(nil, nil)
|
|
115
110
|
end
|
|
116
111
|
|
|
117
|
-
def create_instance(parent_instance,
|
|
118
|
-
unless unique_instance?(parent_instance,
|
|
119
|
-
message = "duplicated instance: #{
|
|
112
|
+
def create_instance(parent_instance, inst_args, array_info, token_range, **optargs)
|
|
113
|
+
unless unique_instance?(parent_instance, inst_args.name, array_info)
|
|
114
|
+
message = "duplicated instance: #{inst_args.name}"
|
|
120
115
|
raise_evaluation_error message, token_range
|
|
121
116
|
end
|
|
122
117
|
|
|
123
|
-
instance = instance_class.new(self, parent_instance,
|
|
118
|
+
instance = instance_class.new(self, parent_instance, inst_args.name, token_range)
|
|
124
119
|
|
|
125
120
|
init_properties(instance)
|
|
126
121
|
eval_body(instance, **optargs)
|
|
127
|
-
|
|
122
|
+
apply_array(instance, array_info)
|
|
123
|
+
apply_inst_values(instance, inst_args.values)
|
|
124
|
+
apply_inst_type(instance, inst_args.type)
|
|
128
125
|
post_build(instance)
|
|
129
126
|
instance.validate
|
|
130
127
|
|
|
@@ -149,9 +146,9 @@ module SystemRDL
|
|
|
149
146
|
def init_properties(instance)
|
|
150
147
|
prop_defs = BuiltinProperties.properties
|
|
151
148
|
prop_defs.each do |prop_def|
|
|
152
|
-
next unless prop_def.target?(instance)
|
|
153
|
-
|
|
154
149
|
prop = prop_def.create(instance)
|
|
150
|
+
next unless prop
|
|
151
|
+
|
|
155
152
|
instance.properties << prop
|
|
156
153
|
end
|
|
157
154
|
end
|
|
@@ -161,9 +158,15 @@ module SystemRDL
|
|
|
161
158
|
@elements.each { |element| element.evaluate(instance, **optargs) }
|
|
162
159
|
end
|
|
163
160
|
|
|
161
|
+
def apply_inst_type(_instance, _inst_type)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
164
|
def apply_inst_values(_instance, _inst_values)
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
+
def apply_array(_instance, _array_info)
|
|
168
|
+
end
|
|
169
|
+
|
|
167
170
|
def post_build(_instance)
|
|
168
171
|
end
|
|
169
172
|
|
|
@@ -20,10 +20,11 @@ module SystemRDL
|
|
|
20
20
|
def evaluate(instance, base, id, **optargs)
|
|
21
21
|
component_definition = find_component_definition(base, id, **optargs)
|
|
22
22
|
check_recursive_instance(instance, component_definition)
|
|
23
|
+
check_inst_type(component_definition)
|
|
23
24
|
check_instantiable(instance, component_definition)
|
|
24
25
|
|
|
25
26
|
@insts.each do |inst|
|
|
26
|
-
inst.evaluate(instance, component_definition, **optargs)
|
|
27
|
+
inst.evaluate(instance, component_definition, inst_type, **optargs)
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -34,7 +35,7 @@ module SystemRDL
|
|
|
34
35
|
definition = component.definitions[id.value]
|
|
35
36
|
next unless definition
|
|
36
37
|
|
|
37
|
-
unless optargs[:test] || (definition
|
|
38
|
+
unless optargs[:test] || instantiable_component?(definition)
|
|
38
39
|
message = "#{definition.layer} instance not supported yet"
|
|
39
40
|
raise_evaluation_error message, token_range
|
|
40
41
|
end
|
|
@@ -45,6 +46,10 @@ module SystemRDL
|
|
|
45
46
|
raise_evaluation_error "undefined component: #{id.value}", token_range
|
|
46
47
|
end
|
|
47
48
|
|
|
49
|
+
def instantiable_component?(definition)
|
|
50
|
+
definition.layer in :addrmap | :regfile | :mem | :reg | :field
|
|
51
|
+
end
|
|
52
|
+
|
|
48
53
|
def check_recursive_instance(instance, component_definition)
|
|
49
54
|
components = instance.definition.upper_layers(include_self: true)
|
|
50
55
|
return if components.none? { |component| component.equal?(component_definition) }
|
|
@@ -53,6 +58,21 @@ module SystemRDL
|
|
|
53
58
|
raise_evaluation_error message, token_range
|
|
54
59
|
end
|
|
55
60
|
|
|
61
|
+
def check_inst_type(component_definition)
|
|
62
|
+
return if component_definition.support_inst_type?(inst_type)
|
|
63
|
+
|
|
64
|
+
message =
|
|
65
|
+
if inst_type
|
|
66
|
+
"#{component_definition.layer} instance with #{inst_type} not allowed"
|
|
67
|
+
else
|
|
68
|
+
"#{component_definition.layer} instance without instance type not allowed"
|
|
69
|
+
end
|
|
70
|
+
raise_evaluation_error message, token_range
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def inst_type
|
|
74
|
+
end
|
|
75
|
+
|
|
56
76
|
def check_instantiable(instance, component_definition)
|
|
57
77
|
return if instance.instantiable?(component_definition)
|
|
58
78
|
|
|
@@ -61,6 +81,24 @@ module SystemRDL
|
|
|
61
81
|
end
|
|
62
82
|
end
|
|
63
83
|
|
|
84
|
+
class InternalComponentInsts < ComponentInsts
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def inst_type
|
|
88
|
+
:internal
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class ExternalComponentInsts < ComponentInsts
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def inst_type
|
|
96
|
+
:external
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
InstArgs = Data.define(:name, :type, :values)
|
|
101
|
+
|
|
64
102
|
class ComponentInst
|
|
65
103
|
include Common
|
|
66
104
|
|
|
@@ -72,9 +110,10 @@ module SystemRDL
|
|
|
72
110
|
|
|
73
111
|
attr_reader :inst_id
|
|
74
112
|
|
|
75
|
-
def evaluate(instance, component_definition, **optargs)
|
|
113
|
+
def evaluate(instance, component_definition, inst_type, **optargs)
|
|
76
114
|
inst_values = eval_inst_values(instance, **optargs)
|
|
77
|
-
|
|
115
|
+
args = InstArgs.new(@inst_id.value, inst_type, inst_values)
|
|
116
|
+
component_definition.create_instances(instance, args, @token_range, **optargs)
|
|
78
117
|
end
|
|
79
118
|
|
|
80
119
|
private
|
|
@@ -32,6 +32,10 @@ module SystemRDL
|
|
|
32
32
|
:field
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
def support_inst_type?(inst_type)
|
|
36
|
+
inst_type.nil?
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
private
|
|
36
40
|
|
|
37
41
|
def instance_class
|
|
@@ -39,33 +43,30 @@ module SystemRDL
|
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
def apply_inst_values(instance, inst_values)
|
|
42
|
-
|
|
46
|
+
assign_bit_range(instance, inst_values)
|
|
43
47
|
apply_reset_value(instance, inst_values)
|
|
44
48
|
check_address_allocation_operator(inst_values)
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
instance.lsb = lsb
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def calc_bit_pos(instance, inst_values)
|
|
59
|
-
width = calc_bit_width(instance, inst_values)
|
|
60
|
-
last_msb = instance.parent.instances.last&.msb
|
|
61
|
-
lsb = (last_msb&.value || -1) + 1
|
|
62
|
-
msb = lsb + (width&.value || 1) - 1
|
|
63
|
-
[msb, lsb].map { |pos| Value.new(pos, :bit, 64, width&.token_range) }
|
|
51
|
+
def assign_bit_range(instance, inst_values)
|
|
52
|
+
if (range = inst_values[:range])
|
|
53
|
+
msb, lsb = range.elements
|
|
54
|
+
instance.msb = msb
|
|
55
|
+
instance.lsb = lsb
|
|
56
|
+
else
|
|
57
|
+
instance.width = bit_width(instance, inst_values)
|
|
58
|
+
end
|
|
64
59
|
end
|
|
65
60
|
|
|
66
|
-
def
|
|
61
|
+
def bit_width(instance, inst_values)
|
|
67
62
|
size = inst_values[:array]
|
|
68
|
-
|
|
63
|
+
unless size
|
|
64
|
+
if (fieldwidth = instance.property_value(:fieldwidth))
|
|
65
|
+
return fieldwidth
|
|
66
|
+
else
|
|
67
|
+
return Value.new(1, :bit, 64, nil)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
69
70
|
|
|
70
71
|
if size.size >= 2
|
|
71
72
|
message = 'multidimensional size specification not allowed for field'
|
|
@@ -90,13 +91,21 @@ module SystemRDL
|
|
|
90
91
|
raise_evaluation_error message, fieldwidth.token_range
|
|
91
92
|
end
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
lsb = instance.lsb
|
|
95
|
-
width = msb.value - lsb.value + 1
|
|
94
|
+
width, width_token_range = extract_width(instance)
|
|
96
95
|
return if width == fieldwidth.value
|
|
97
96
|
|
|
98
97
|
message = "bit width mismatch: instance width #{width} fieldwidth property #{fieldwidth}"
|
|
99
|
-
raise_evaluation_error message,
|
|
98
|
+
raise_evaluation_error message, *width_token_range
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def extract_width(instance)
|
|
102
|
+
if instance.msb
|
|
103
|
+
pos = [instance.msb.value, instance.lsb.value].sort
|
|
104
|
+
width = pos[1] - pos[0] + 1
|
|
105
|
+
[width, [instance.msb.token_range, instance.lsb.token_range]]
|
|
106
|
+
else
|
|
107
|
+
[instance.width.value, [instance.width.token_range].compact]
|
|
108
|
+
end
|
|
100
109
|
end
|
|
101
110
|
|
|
102
111
|
def apply_reset_value(instance, inst_values)
|
|
@@ -120,7 +129,7 @@ module SystemRDL
|
|
|
120
129
|
end
|
|
121
130
|
|
|
122
131
|
def check_reset_value(instance, reset_value)
|
|
123
|
-
width = instance
|
|
132
|
+
width, _ = extract_width(instance)
|
|
124
133
|
range = 0..((2**width) - 1)
|
|
125
134
|
return if range.include?(reset_value.value)
|
|
126
135
|
|
|
@@ -224,6 +233,11 @@ module SystemRDL
|
|
|
224
233
|
class FieldInstance < Instance
|
|
225
234
|
attr_accessor :msb
|
|
226
235
|
attr_accessor :lsb
|
|
236
|
+
attr_accessor :width
|
|
237
|
+
|
|
238
|
+
def virtual_field?
|
|
239
|
+
parent.virtual_reg?
|
|
240
|
+
end
|
|
227
241
|
|
|
228
242
|
def definable?(_definition)
|
|
229
243
|
false
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
module InstTypeAwareComponent
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def apply_inst_type(instance, inst_type)
|
|
9
|
+
instance.external = inst_type == :external
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module InstTypeAwareInstance
|
|
14
|
+
attr_accessor :external
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
module SystemRDL
|
|
4
4
|
module Evaluator
|
|
5
5
|
class Instance
|
|
6
|
-
def initialize(definition, parent, name,
|
|
6
|
+
def initialize(definition, parent, name, token_range)
|
|
7
7
|
@definition = definition
|
|
8
8
|
@parent = parent
|
|
9
9
|
@name = name
|
|
10
|
-
@array_info = array_info
|
|
11
10
|
@token_range = token_range
|
|
12
11
|
@properties = []
|
|
13
12
|
@instances = []
|
|
@@ -35,14 +34,13 @@ module SystemRDL
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def full_name
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
until current.root?
|
|
41
|
-
elements.unshift(current)
|
|
42
|
-
current = current.parent
|
|
43
|
-
end
|
|
37
|
+
upper_instances(include_root: false, include_self: true).map(&:element_name).join('.')
|
|
38
|
+
end
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
def upper_instances(include_root: false, include_self: false)
|
|
41
|
+
instances = (root? && []) || parent.upper_instances(include_root:, include_self: true)
|
|
42
|
+
instances << self if (root? && include_root) || (!root? && include_self)
|
|
43
|
+
instances
|
|
46
44
|
end
|
|
47
45
|
|
|
48
46
|
def layer
|
|
@@ -61,6 +59,10 @@ module SystemRDL
|
|
|
61
59
|
layer == :regfile
|
|
62
60
|
end
|
|
63
61
|
|
|
62
|
+
def mem?
|
|
63
|
+
layer == :mem
|
|
64
|
+
end
|
|
65
|
+
|
|
64
66
|
def reg?
|
|
65
67
|
layer == :reg
|
|
66
68
|
end
|
|
@@ -70,27 +72,19 @@ module SystemRDL
|
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
def structural_component?
|
|
73
|
-
addrmap? || regfile? || reg? || field?
|
|
75
|
+
addrmap? || regfile? || mem? || reg? || field?
|
|
74
76
|
end
|
|
75
77
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def array_sizes
|
|
85
|
-
array_info&.sizes
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def first_element?
|
|
89
|
-
!array? || array_info.first
|
|
78
|
+
def find_addrmap
|
|
79
|
+
if RUBY_VERSION >= '4.0'
|
|
80
|
+
upper_instances(include_root: false, include_self: true).rfind(&:addrmap?)
|
|
81
|
+
else
|
|
82
|
+
upper_instances(include_root: false, include_self: true).reverse_each.find(&:addrmap?)
|
|
83
|
+
end
|
|
90
84
|
end
|
|
91
85
|
|
|
92
|
-
def
|
|
93
|
-
|
|
86
|
+
def array?
|
|
87
|
+
false
|
|
94
88
|
end
|
|
95
89
|
|
|
96
90
|
def property(name)
|
|
@@ -112,8 +106,8 @@ module SystemRDL
|
|
|
112
106
|
end
|
|
113
107
|
|
|
114
108
|
def finalize
|
|
115
|
-
@definition.finalize(self)
|
|
116
109
|
@instances.each(&:finalize)
|
|
110
|
+
@definition.finalize(self)
|
|
117
111
|
end
|
|
118
112
|
end
|
|
119
113
|
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class MemDefinition < ComponentDefinition
|
|
6
|
+
include InstTypeAwareComponent
|
|
7
|
+
include BlockComponent
|
|
8
|
+
|
|
9
|
+
def validate(instance)
|
|
10
|
+
check_positive_value(instance, :mementries)
|
|
11
|
+
check_memwidth(instance)
|
|
12
|
+
check_regwidth(instance)
|
|
13
|
+
check_virtual_field_sw(instance)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def revalidate(instance)
|
|
17
|
+
check_virtual_field_sw(instance)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def finalize(instance)
|
|
21
|
+
check_virtual_field_pos(instance)
|
|
22
|
+
allocate_addresses(instance)
|
|
23
|
+
check_address_operations(instance)
|
|
24
|
+
check_reg_size(instance)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def layer
|
|
28
|
+
:mem
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def support_inst_type?(inst_type)
|
|
32
|
+
inst_type == :external
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def instance_class
|
|
38
|
+
MemInstance
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def apply_inst_values(instance, inst_values)
|
|
42
|
+
apply_address_operations(instance, inst_values)
|
|
43
|
+
check_range(inst_values)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def post_build(instance)
|
|
47
|
+
apply_default_memwidth(instance)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def apply_default_memwidth(instance)
|
|
51
|
+
return if no_regs?(instance)
|
|
52
|
+
|
|
53
|
+
property = instance.property(:memwidth)
|
|
54
|
+
return if property.value
|
|
55
|
+
|
|
56
|
+
entrywidth = Value.new(instance.entrywidth, :bit, 64, nil)
|
|
57
|
+
property.assign(entrywidth)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def check_memwidth(instance)
|
|
61
|
+
check_positive_value(instance, :memwidth)
|
|
62
|
+
|
|
63
|
+
memwidth = instance.property_value(:memwidth)
|
|
64
|
+
return if memwidth || !no_regs?(instance)
|
|
65
|
+
|
|
66
|
+
message = 'omitting memwidth without virtual regs not allowed'
|
|
67
|
+
raise_evaluation_error message, instance.token_range
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def check_positive_value(instance, prop_name)
|
|
71
|
+
value = instance.property_value(prop_name)
|
|
72
|
+
return if value.nil? || value.value >= 1
|
|
73
|
+
|
|
74
|
+
message = "#{prop_name} must be positive"
|
|
75
|
+
raise_evaluation_error message, value.token_range
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def check_regwidth(instance)
|
|
79
|
+
return if no_regs?(instance)
|
|
80
|
+
|
|
81
|
+
entrywidth = instance.entrywidth
|
|
82
|
+
instance.instances.each do |reg|
|
|
83
|
+
regwidth = reg.property_value(:regwidth).value
|
|
84
|
+
next if regwidth <= entrywidth
|
|
85
|
+
|
|
86
|
+
memwidth = instance.property_value(:memwidth)
|
|
87
|
+
message =
|
|
88
|
+
'regwidth larger than entry width not allowed: ' \
|
|
89
|
+
"entry width #{entrywidth} (memwidth #{memwidth}) regwidth #{regwidth}"
|
|
90
|
+
raise_evaluation_error message, reg.token_range
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def check_virtual_field_pos(instance)
|
|
95
|
+
return if no_regs?(instance)
|
|
96
|
+
|
|
97
|
+
memwidth = instance.property_value(:memwidth).value
|
|
98
|
+
instance.instances.flat_map(&:instances).each do |field|
|
|
99
|
+
next if valid_virtual_field_pos?(field, memwidth)
|
|
100
|
+
|
|
101
|
+
message =
|
|
102
|
+
'virtual field outside memwidth not allowed: ' \
|
|
103
|
+
"memwidth #{memwidth} msb #{field.msb} lsb #{field.lsb}"
|
|
104
|
+
raise_evaluation_error message, field.token_range
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def valid_virtual_field_pos?(field, memwidth)
|
|
109
|
+
[field.msb.value, field.lsb.value].sort[1] < memwidth
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def check_virtual_field_sw(instance)
|
|
113
|
+
return if no_regs?(instance)
|
|
114
|
+
|
|
115
|
+
mem_sw = instance.property_value(:sw).value
|
|
116
|
+
instance.instances.flat_map(&:instances).each do |field|
|
|
117
|
+
field_sw = field.property_value(:sw).value
|
|
118
|
+
next if field_sw == mem_sw
|
|
119
|
+
|
|
120
|
+
message =
|
|
121
|
+
'mismatch between mem sw and virtual field sw: ' \
|
|
122
|
+
"mem #{mem_sw} virtual field #{field_sw}"
|
|
123
|
+
raise_evaluation_error message, field.token_range
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def check_reg_size(instance)
|
|
128
|
+
return if no_regs?(instance)
|
|
129
|
+
|
|
130
|
+
size = instance.size
|
|
131
|
+
instance.instances.each do |reg|
|
|
132
|
+
reg_addr = reg.address.value
|
|
133
|
+
reg_size = reg.size
|
|
134
|
+
next if (reg_addr + reg_size) <= size
|
|
135
|
+
|
|
136
|
+
message =
|
|
137
|
+
'virtual reg outside mem area not allowed: ' \
|
|
138
|
+
"mem size #{size} reg address 0x#{reg_addr.to_s(16)} reg size #{reg_size}"
|
|
139
|
+
raise_evaluation_error message, reg.token_range
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def no_regs?(instance)
|
|
144
|
+
instance.instances.empty?
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class MemInstance < Instance
|
|
149
|
+
include InstTypeAwareInstance
|
|
150
|
+
include BlockInstance
|
|
151
|
+
|
|
152
|
+
def entrywidth
|
|
153
|
+
@entrywidth ||=
|
|
154
|
+
if (memwidth = property_value(:memwidth)&.value)
|
|
155
|
+
if memwidth <= 8
|
|
156
|
+
8
|
|
157
|
+
elsif memwidth.nobits?(memwidth - 1)
|
|
158
|
+
memwidth
|
|
159
|
+
else
|
|
160
|
+
2**memwidth.bit_length
|
|
161
|
+
end
|
|
162
|
+
else
|
|
163
|
+
instances
|
|
164
|
+
.map { |inst| inst.property_value(:regwidth).value }
|
|
165
|
+
.max
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def accesswidth
|
|
170
|
+
(instances.empty? && entrywidth) || super
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def size
|
|
174
|
+
@size ||= begin
|
|
175
|
+
width = entrywidth / 8
|
|
176
|
+
entries = property_value(:mementries).value
|
|
177
|
+
width * entries
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def definable?(definition)
|
|
182
|
+
definition.layer in :reg | :field
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def instantiable?(definition)
|
|
186
|
+
definition.layer in :reg
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -130,6 +130,16 @@ module SystemRDL
|
|
|
130
130
|
ComponentInsts.new(insts, node.token_range)
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
+
def on_internal_component_insts(node)
|
|
134
|
+
insts = process_all(node.children)
|
|
135
|
+
InternalComponentInsts.new(insts, node.token_range)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def on_external_component_insts(node)
|
|
139
|
+
insts = process_all(node.children)
|
|
140
|
+
ExternalComponentInsts.new(insts, node.token_range)
|
|
141
|
+
end
|
|
142
|
+
|
|
133
143
|
def on_explicit_component_inst(node)
|
|
134
144
|
id = process(node.children[0])
|
|
135
145
|
insts = process(node.children[1])
|
|
@@ -157,6 +167,7 @@ module SystemRDL
|
|
|
157
167
|
case node.children[0].to_sym
|
|
158
168
|
when :addrmap then AddrMapDefinition
|
|
159
169
|
when :regfile then RegFileDefinition
|
|
170
|
+
when :mem then MemDefinition
|
|
160
171
|
when :reg then RegDefinition
|
|
161
172
|
when :field then FieldDefinition
|
|
162
173
|
end
|
|
@@ -69,25 +69,36 @@ module SystemRDL
|
|
|
69
69
|
|
|
70
70
|
attr_reader :name
|
|
71
71
|
attr_accessor :targets
|
|
72
|
+
attr_accessor :exist
|
|
72
73
|
attr_accessor :types
|
|
73
74
|
attr_accessor :ref_target
|
|
74
75
|
attr_accessor :dynamic_assign
|
|
75
76
|
attr_accessor :per_element_assign
|
|
76
77
|
attr_accessor :default_value
|
|
77
78
|
|
|
79
|
+
def create(instance)
|
|
80
|
+
return unless target?(instance) && exist?(instance)
|
|
81
|
+
|
|
82
|
+
value = eval_value(instance)
|
|
83
|
+
Property.new(instance, self, value)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
78
88
|
def target?(instance)
|
|
79
89
|
return false if instance.root?
|
|
80
90
|
|
|
81
91
|
targets.nil? || targets.include?(instance.layer)
|
|
82
92
|
end
|
|
83
93
|
|
|
84
|
-
def
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
def exist?(instance)
|
|
95
|
+
if @exist.is_a?(Proc)
|
|
96
|
+
@exist.call(instance)
|
|
97
|
+
else
|
|
98
|
+
@exist
|
|
99
|
+
end
|
|
87
100
|
end
|
|
88
101
|
|
|
89
|
-
private
|
|
90
|
-
|
|
91
102
|
def eval_value(instance)
|
|
92
103
|
value = instance.definition.find_default_property(name)
|
|
93
104
|
return value if value
|
|
@@ -101,7 +112,7 @@ module SystemRDL
|
|
|
101
112
|
|
|
102
113
|
return if value.nil?
|
|
103
114
|
|
|
104
|
-
create_value(value)
|
|
115
|
+
value.is_a?(Value) ? value : create_value(value)
|
|
105
116
|
end
|
|
106
117
|
|
|
107
118
|
def create_value(value)
|