systemrdl 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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +127 -0
- data/lib/systemrdl/error.rb +55 -0
- data/lib/systemrdl/evaluator/address_allocation.rb +126 -0
- data/lib/systemrdl/evaluator/address_operation.rb +103 -0
- data/lib/systemrdl/evaluator/addrmap.rb +67 -0
- data/lib/systemrdl/evaluator/array_component.rb +42 -0
- data/lib/systemrdl/evaluator/builtin_properties.rb +400 -0
- data/lib/systemrdl/evaluator/common.rb +22 -0
- data/lib/systemrdl/evaluator/component_definition.rb +185 -0
- data/lib/systemrdl/evaluator/component_insts.rb +106 -0
- data/lib/systemrdl/evaluator/container_component.rb +16 -0
- data/lib/systemrdl/evaluator/field.rb +245 -0
- data/lib/systemrdl/evaluator/instance.rb +120 -0
- data/lib/systemrdl/evaluator/list.rb +26 -0
- data/lib/systemrdl/evaluator/literal.rb +173 -0
- data/lib/systemrdl/evaluator/operation.rb +241 -0
- data/lib/systemrdl/evaluator/processor.rb +166 -0
- data/lib/systemrdl/evaluator/property.rb +116 -0
- data/lib/systemrdl/evaluator/property_assignment.rb +220 -0
- data/lib/systemrdl/evaluator/reference.rb +135 -0
- data/lib/systemrdl/evaluator/reg.rb +156 -0
- data/lib/systemrdl/evaluator/regfile.rb +33 -0
- data/lib/systemrdl/evaluator/root.rb +39 -0
- data/lib/systemrdl/evaluator/value.rb +13 -0
- data/lib/systemrdl/evaluator.rb +14 -0
- data/lib/systemrdl/model/instance.rb +194 -0
- data/lib/systemrdl/model/value.rb +54 -0
- data/lib/systemrdl/model.rb +11 -0
- data/lib/systemrdl/parser/generated_parser.rb +2808 -0
- data/lib/systemrdl/parser/node.rb +17 -0
- data/lib/systemrdl/parser/parser.rb +86 -0
- data/lib/systemrdl/parser/scanner.rb +251 -0
- data/lib/systemrdl/parser/systemrdl.y +448 -0
- data/lib/systemrdl/parser/token.rb +58 -0
- data/lib/systemrdl/parser.rb +11 -0
- data/lib/systemrdl/version.rb +5 -0
- data/lib/systemrdl.rb +90 -0
- metadata +96 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
module PropertyAssignmentCommon
|
|
6
|
+
def initialize(value, token_range)
|
|
7
|
+
super(token_range)
|
|
8
|
+
@value = value
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def evaluate(instance, **optargs)
|
|
12
|
+
properties = find_properties(instance)
|
|
13
|
+
check_properties(instance, properties)
|
|
14
|
+
|
|
15
|
+
properties.each do |property|
|
|
16
|
+
value = eval_value(instance, property, **optargs)
|
|
17
|
+
assign_property(instance, property, value)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def check_properties(_instance, _properties)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def eval_value(instance, property, **optargs)
|
|
27
|
+
value =
|
|
28
|
+
if @value
|
|
29
|
+
@value.evaluate(instance, **optargs)
|
|
30
|
+
else
|
|
31
|
+
# true value is implicitly applied
|
|
32
|
+
# when the assignment value is omitted.
|
|
33
|
+
Value.new(true, :boolean, 1, @token_range)
|
|
34
|
+
end
|
|
35
|
+
check_value(property, value)
|
|
36
|
+
|
|
37
|
+
if match_integral_type?(property, value)
|
|
38
|
+
cast_integral_value(property, value)
|
|
39
|
+
else
|
|
40
|
+
value
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def check_value(property, value)
|
|
45
|
+
check_type_compatibility(property, value)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_type_compatibility(property, value)
|
|
49
|
+
return if property.types.include?(value.type) || match_integral_type?(property, value)
|
|
50
|
+
|
|
51
|
+
message =
|
|
52
|
+
"#{value.type} type not supported by #{property.name} property: " \
|
|
53
|
+
"expected #{type_label(property)}"
|
|
54
|
+
raise_evaluation_error message, @token_range
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def type_label(property)
|
|
58
|
+
types = property.types
|
|
59
|
+
if types.size == 1
|
|
60
|
+
types[0]
|
|
61
|
+
else
|
|
62
|
+
[types[..-2].join(', '), types[-1]].join(' or ')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def match_integral_type?(property, value)
|
|
67
|
+
integral_types = [:bit, :longint, :boolean]
|
|
68
|
+
return false unless integral_types.include?(value.type)
|
|
69
|
+
|
|
70
|
+
(integral_types & property.types).any?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def cast_integral_value(property, value)
|
|
74
|
+
if property.types.include?(:bit)
|
|
75
|
+
to_bit(value)
|
|
76
|
+
elsif property.types.include?(:longint)
|
|
77
|
+
to_longint(value)
|
|
78
|
+
else
|
|
79
|
+
to_boolean(value)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def to_bit(value)
|
|
84
|
+
return value if value.type == :bit
|
|
85
|
+
|
|
86
|
+
if value.type == :longint
|
|
87
|
+
Value.new(value.value, :bit, 64, value.token_range)
|
|
88
|
+
elsif value.value
|
|
89
|
+
Value.new(1, :bit, 1, value.token_range)
|
|
90
|
+
else
|
|
91
|
+
Value.new(0, :bit, 1, value.token_range)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def to_longint(value)
|
|
96
|
+
return value if value.type == :longint
|
|
97
|
+
|
|
98
|
+
if value.type == :bit
|
|
99
|
+
v = value.value & 0xFFFF_FFFF_FFFF_FFFF
|
|
100
|
+
Value.new(v, :longint, 64, value.token_range)
|
|
101
|
+
elsif value.value
|
|
102
|
+
Value.new(1, :longint, 64, value.token_range)
|
|
103
|
+
else
|
|
104
|
+
Value.new(0, :longint, 64, value.token_range)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def to_boolean(value)
|
|
109
|
+
return value if value.type == :boolean
|
|
110
|
+
|
|
111
|
+
Value.new(value.value != 0, :boolean, 1, value.token_range)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class PropertyAssignment
|
|
116
|
+
include Common
|
|
117
|
+
include PropertyAssignmentCommon
|
|
118
|
+
|
|
119
|
+
def initialize(prop_ref, value, token_range)
|
|
120
|
+
super(value, token_range)
|
|
121
|
+
@prop_ref = prop_ref
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def find_properties(instance)
|
|
127
|
+
@prop_ref.find(instance, allow_array_ref: false)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def check_properties(_instance, properties)
|
|
131
|
+
property = properties[0]
|
|
132
|
+
return unless property&.assigned?
|
|
133
|
+
|
|
134
|
+
message = "#{property.name} already assigned in this scope"
|
|
135
|
+
raise_evaluation_error message, token_range
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def assign_property(_instance, property, value)
|
|
139
|
+
property.assign(value)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class PostPropertyAssignment
|
|
144
|
+
include Common
|
|
145
|
+
include PropertyAssignmentCommon
|
|
146
|
+
|
|
147
|
+
def initialize(prop_ref, value, token_range)
|
|
148
|
+
super(value, token_range)
|
|
149
|
+
@prop_ref = prop_ref
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
def check_value(property, value)
|
|
155
|
+
super
|
|
156
|
+
|
|
157
|
+
check_ref_target(value)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def check_ref_target(value)
|
|
161
|
+
return if value.type != :property_reference
|
|
162
|
+
|
|
163
|
+
property = value.value
|
|
164
|
+
return if property.ref_target?
|
|
165
|
+
|
|
166
|
+
message = "reference to #{property.name} property not allowed"
|
|
167
|
+
raise_evaluation_error message, @token_range
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def find_properties(instance)
|
|
171
|
+
@prop_ref.find(instance, allow_array_ref: true)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def check_properties(_instance, properties)
|
|
175
|
+
properties.each do |property|
|
|
176
|
+
next unless property
|
|
177
|
+
|
|
178
|
+
unless property.dynamic_assign?
|
|
179
|
+
message = "dynamic assignment to #{property.name} property not allowed"
|
|
180
|
+
raise_evaluation_error message, token_range
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if !property.per_element_assign? && @prop_ref.array_select?
|
|
184
|
+
message = "element assignment to #{property.name} property not allowed"
|
|
185
|
+
raise_evaluation_error message, token_range
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def assign_property(_instance, property, value)
|
|
191
|
+
property.assign(value)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
class DefaultPropertyAssignment
|
|
196
|
+
include Common
|
|
197
|
+
include PropertyAssignmentCommon
|
|
198
|
+
|
|
199
|
+
def initialize(prop_name, value, token_range)
|
|
200
|
+
super(value, token_range)
|
|
201
|
+
@prop_name = prop_name
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
private
|
|
205
|
+
|
|
206
|
+
def find_properties(_instance)
|
|
207
|
+
prop_def = BuiltinProperties.find(@prop_name.value)
|
|
208
|
+
return [prop_def] if prop_def
|
|
209
|
+
|
|
210
|
+
message = "undefined property: #{@prop_name.value}"
|
|
211
|
+
raise_evaluation_error message, token_range
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def assign_property(instance, _property, value)
|
|
215
|
+
definition = instance.definition
|
|
216
|
+
definition.assign_default_property(@prop_name.value, value, token_range)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class InstanceRefElement
|
|
6
|
+
include Common
|
|
7
|
+
|
|
8
|
+
def initialize(id, array, token_range)
|
|
9
|
+
super(token_range)
|
|
10
|
+
@id = id
|
|
11
|
+
@array = array
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :id
|
|
15
|
+
attr_reader :array
|
|
16
|
+
|
|
17
|
+
def find(base)
|
|
18
|
+
result = find_instance(base)
|
|
19
|
+
return result unless result.empty?
|
|
20
|
+
|
|
21
|
+
inst_name =
|
|
22
|
+
if array_select?
|
|
23
|
+
array
|
|
24
|
+
.elements
|
|
25
|
+
.inject([id.value]) { |elements, select| elements << "[#{select.value}]" }
|
|
26
|
+
.join
|
|
27
|
+
else
|
|
28
|
+
id.value.to_s
|
|
29
|
+
end
|
|
30
|
+
raise_evaluation_error "unresolvable instance: #{inst_name}", token_range
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def array_select?
|
|
34
|
+
!array.nil?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def find_instance(base)
|
|
40
|
+
base.instances.select do |inst|
|
|
41
|
+
inst.name == id.value && match_array_indices?(inst)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def match_array_indices?(instance)
|
|
46
|
+
# non array instance && array select
|
|
47
|
+
return false if !instance.array? && array_select?
|
|
48
|
+
|
|
49
|
+
# non array instance or whole array
|
|
50
|
+
return true unless array_select?
|
|
51
|
+
|
|
52
|
+
# check size
|
|
53
|
+
return false if instance.array_indices.size != array.size
|
|
54
|
+
|
|
55
|
+
instance
|
|
56
|
+
.array_indices
|
|
57
|
+
.zip(array.elements)
|
|
58
|
+
.all? { |index, select| index == select.value }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class InstanceRef
|
|
63
|
+
include Common
|
|
64
|
+
|
|
65
|
+
def initialize(elements, token_range)
|
|
66
|
+
super(token_range)
|
|
67
|
+
@elements = elements
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
attr_reader :elements
|
|
71
|
+
|
|
72
|
+
def evaluate(instance, **_optargs)
|
|
73
|
+
find(instance, allow_array_ref: false)[0].to_value(token_range)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def find(instance, allow_array_ref: false)
|
|
77
|
+
result = @elements.inject([instance]) do |instances, element|
|
|
78
|
+
process_instance_ref_element(instances, element)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return result if allow_array_ref || result.size <= 1
|
|
82
|
+
|
|
83
|
+
message = 'reference to array instance not allowed'
|
|
84
|
+
raise_evaluation_error message, token_range
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def array_select?
|
|
88
|
+
elements.any?(&:array_select?)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def process_instance_ref_element(instances, element)
|
|
94
|
+
instances.flat_map { |inst| element.find(inst) }
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class PropRef
|
|
99
|
+
include Common
|
|
100
|
+
|
|
101
|
+
def initialize(instance_ref, prop, token_range)
|
|
102
|
+
super(token_range)
|
|
103
|
+
@instance_ref = instance_ref
|
|
104
|
+
@prop = prop
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
attr_reader :instance_ref
|
|
108
|
+
attr_reader :prop
|
|
109
|
+
|
|
110
|
+
def evaluate(instance, **_optargs)
|
|
111
|
+
find(instance, allow_array_ref: false)[0].to_value(token_range)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def find(instance, allow_array_ref: false)
|
|
115
|
+
insts =
|
|
116
|
+
if @instance_ref
|
|
117
|
+
@instance_ref.find(instance, allow_array_ref:)
|
|
118
|
+
else
|
|
119
|
+
[instance]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
insts.map do |inst|
|
|
123
|
+
prop = inst.property(@prop.value)
|
|
124
|
+
next prop if prop
|
|
125
|
+
|
|
126
|
+
raise_evaluation_error "undefined property: #{@prop.value}", token_range
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def array_select?
|
|
131
|
+
@instance_ref&.array_select? || false
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class RegDefinition < ComponentDefinition
|
|
6
|
+
include AddressOperation
|
|
7
|
+
include ArrayComponent
|
|
8
|
+
include ContainerComponent
|
|
9
|
+
|
|
10
|
+
def validate(instance)
|
|
11
|
+
check_structural_component_instances(instance)
|
|
12
|
+
check_regwidth(instance)
|
|
13
|
+
check_accesswidth(instance)
|
|
14
|
+
check_overlapping_fields(instance)
|
|
15
|
+
check_fields_out_of_register(instance)
|
|
16
|
+
check_fields_spanning_sub_word_boundary(instance)
|
|
17
|
+
check_address_operations(instance)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def revalidate(instance)
|
|
21
|
+
check_accesswidth(instance)
|
|
22
|
+
check_fields_spanning_sub_word_boundary(instance)
|
|
23
|
+
check_address_operations(instance)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def layer
|
|
27
|
+
:reg
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def instance_class
|
|
33
|
+
RegInstance
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def apply_inst_values(instance, inst_values)
|
|
37
|
+
apply_address_operations(instance, inst_values)
|
|
38
|
+
check_range(inst_values)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def post_build(instance)
|
|
42
|
+
apply_default_accesswidth(instance)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def apply_default_accesswidth(instance)
|
|
46
|
+
property = instance.property(:accesswidth)
|
|
47
|
+
return if property.value
|
|
48
|
+
|
|
49
|
+
regwidth = instance.property_value(:regwidth)
|
|
50
|
+
property.assign(regwidth)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def check_regwidth(instance)
|
|
54
|
+
check_power_of_2(instance, :regwidth, 8)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def check_accesswidth(instance)
|
|
58
|
+
check_power_of_2(instance, :accesswidth, 8)
|
|
59
|
+
|
|
60
|
+
regwidth = instance.property_value(:regwidth)
|
|
61
|
+
accesswidth = instance.property_value(:accesswidth)
|
|
62
|
+
return if accesswidth.value <= regwidth.value
|
|
63
|
+
|
|
64
|
+
message = "accesswidth exceeds regwidth: accesswidth = #{accesswidth} regwidth = #{regwidth}"
|
|
65
|
+
raise_evaluation_error message, accesswidth.token_range, regwidth.token_range
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def check_overlapping_fields(instance)
|
|
69
|
+
instance.instances.combination(2).each do |(field_a, field_b)|
|
|
70
|
+
next unless overlapping_field_pair?(field_a, field_b)
|
|
71
|
+
|
|
72
|
+
message = 'overlapping fields not allowed'
|
|
73
|
+
raise_evaluation_error message, field_a.token_range, field_b.token_range
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def overlapping_field_pair?(field_a, field_b)
|
|
78
|
+
range_a = (field_a.lsb.value..field_a.msb.value)
|
|
79
|
+
range_b = (field_b.lsb.value..field_b.msb.value)
|
|
80
|
+
return false unless range_a.include?(range_b.begin) || range_b.include?(range_a.begin)
|
|
81
|
+
|
|
82
|
+
r_a = field_a.sw_readable?
|
|
83
|
+
w_a = field_a.sw_writable?
|
|
84
|
+
r_b = field_b.sw_readable?
|
|
85
|
+
w_b = field_b.sw_writable?
|
|
86
|
+
(r_a && r_b) || (w_a && w_b)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def check_fields_out_of_register(instance)
|
|
90
|
+
regwidth = instance.property_value(:regwidth).value
|
|
91
|
+
instance.instances.each do |field|
|
|
92
|
+
msb = field.msb.value
|
|
93
|
+
lsb = field.lsb.value
|
|
94
|
+
next if msb < regwidth
|
|
95
|
+
|
|
96
|
+
message = "field out of register: bit position [#{msb}:#{lsb}] regwidth #{regwidth}"
|
|
97
|
+
raise_evaluation_error message, field.token_range
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def check_fields_spanning_sub_word_boundary(instance)
|
|
102
|
+
accesswidth = instance.property_value(:accesswidth).value
|
|
103
|
+
instance.instances.each do |field|
|
|
104
|
+
next unless field_with_side_effect?(field)
|
|
105
|
+
|
|
106
|
+
msb = field.msb.value
|
|
107
|
+
lsb = field.lsb.value
|
|
108
|
+
next if (msb / accesswidth) == (lsb / accesswidth)
|
|
109
|
+
|
|
110
|
+
message =
|
|
111
|
+
'field spanning sub-word boundary not allowed: ' \
|
|
112
|
+
"bit position [#{msb}:#{lsb}] accesswidth #{accesswidth}"
|
|
113
|
+
raise_evaluation_error message, field.token_range
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def field_with_side_effect?(field)
|
|
118
|
+
sw = field.property_value(:sw).value
|
|
119
|
+
return true if sw in :rw | :w
|
|
120
|
+
|
|
121
|
+
[:onread, :rclr, :rset]
|
|
122
|
+
.any? { |prop| field.property_value(prop)&.value }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class RegInstance < Instance
|
|
127
|
+
attr_accessor :address
|
|
128
|
+
attr_accessor :stride
|
|
129
|
+
attr_accessor :alignment
|
|
130
|
+
|
|
131
|
+
def definable?(definition)
|
|
132
|
+
definition.layer in :field
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def instantiable?(definition)
|
|
136
|
+
definable?(definition)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def accesswidth
|
|
140
|
+
property_value(:accesswidth).value
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def size
|
|
144
|
+
property_value(:regwidth).value / 8
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def sw_readable?
|
|
148
|
+
instances.any?(&:sw_readable?)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def sw_writable?
|
|
152
|
+
instances.any?(&:sw_writable?)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class RegFileDefinition < ComponentDefinition
|
|
6
|
+
include ContainerComponent
|
|
7
|
+
|
|
8
|
+
def validate(instance)
|
|
9
|
+
check_structural_component_instances(instance)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def layer
|
|
13
|
+
:regfile
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def instance_class
|
|
19
|
+
RegFileInstance
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class RegFileInstance < Instance
|
|
24
|
+
def definable?(definition)
|
|
25
|
+
definition.layer in :regfile | :reg | :field
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def instantiable?(definition)
|
|
29
|
+
definition.layer in :regfile | :reg
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class Root < ComponentDefinition
|
|
6
|
+
def layer
|
|
7
|
+
:root
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(elements, token_range)
|
|
11
|
+
super(Value.new(:root, nil, nil, nil), elements, nil, token_range)
|
|
12
|
+
connect(nil, nil)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def evaluate(instance, **optargs)
|
|
16
|
+
inherit(instance) if instance&.root?
|
|
17
|
+
root = create_instance(nil, :root, nil, nil, nil, **optargs)
|
|
18
|
+
root.finalize
|
|
19
|
+
root
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def instance_class
|
|
25
|
+
RootInstance
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def inherit(instance)
|
|
29
|
+
definitions.merge!(instance.definition.definitions)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class RootInstance < Instance
|
|
34
|
+
def definable?(_definition)
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
def self.evaluate(ast, root = nil, **optargs)
|
|
6
|
+
evaluator = build_evaluator(ast)
|
|
7
|
+
evaluator.evaluate(root, **optargs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.build_evaluator(ast)
|
|
11
|
+
Processor.new.process(ast)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|