ipxact-ruby 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +15 -0
- data/.gitignore +2 -0
- data/README.html +89 -0
- data/README.mdown +91 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +17 -0
- data/lib/ipxact.rb +263 -0
- data/lib/ipxact/component.rb +235 -0
- data/lib/ipxact/parser.rb +27 -0
- data/lib/ipxact/parser/bus_data_parser.rb +229 -0
- data/lib/ipxact/parser/component_data_parser.rb +309 -0
- data/lib/ipxact/parser/platform_data_parser.rb +63 -0
- data/lib/ipxact/pathfinder/graph_pathfinder.rb +191 -0
- data/lib/ipxact/platform.rb +43 -0
- data/schemas/abstractionDefinition.xsd +332 -0
- data/schemas/abstractor.xsd +156 -0
- data/schemas/autoConfigure.xsd +226 -0
- data/schemas/busDefinition.xsd +99 -0
- data/schemas/busInterface.xsd +640 -0
- data/schemas/commonStructures.xsd +189 -0
- data/schemas/component.xsd +253 -0
- data/schemas/configurable.xsd +82 -0
- data/schemas/constraints.xsd +283 -0
- data/schemas/design.xsd +105 -0
- data/schemas/designConfig.xsd +144 -0
- data/schemas/file.xsd +560 -0
- data/schemas/fileType.xsd +86 -0
- data/schemas/generator.xsd +240 -0
- data/schemas/identifier.xsd +93 -0
- data/schemas/index.xsd +67 -0
- data/schemas/memoryMap.xsd +1007 -0
- data/schemas/model.xsd +291 -0
- data/schemas/port.xsd +441 -0
- data/schemas/signalDrivers.xsd +220 -0
- data/schemas/simpleTypes.xsd +90 -0
- data/schemas/subInstances.xsd +256 -0
- data/spec/integration/bus_data_extraction_spec.rb +105 -0
- data/spec/integration/data_calculation_spec.rb +133 -0
- data/spec/integration/data_construction_spec.rb +52 -0
- data/spec/integration/general_spec.rb +121 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_initiator_port.h +135 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_initiator_port.tpp +247 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_initiator_port_base.h +189 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_router.h +205 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_router.tpp +278 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_slave_base.h +115 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_slave_base.tpp +126 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_target_port.h +168 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_target_port_base.h +133 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/pv_tlm_if.h +280 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/PV/user_types.h +38 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/Leon2Platform/Leon2Platform.xml +77 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/Leon2Platform/design_Leon2Platform.xml +156 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/Leon2Platform/tlmsrc/Leon2Platform.h +149 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/apbSubSystem/apbSubSystem.xml +406 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/apbSubSystem/design_apbSubSystem.xml +135 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM1/apbSubSystem/tlmsrc/apbSubSystem.h +133 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/Leon2Platform/Leon2Platform.xml +77 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/Leon2Platform/design_Leon2Platform.xml +157 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/Leon2Platform/tlmsrc/Leon2Platform.h +150 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/apbSubSystem/apbSubSystem.xml +422 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/apbSubSystem/designConfig_apbSubSystem.xml +79 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/apbSubSystem/design_apbSubSystem.xml +184 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM2/apbSubSystem/tlmsrc/apbSubSystem.h +164 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/Leon2Platform/Leon2Platform.xml +105 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/Leon2Platform/design_Leon2Platform.xml +157 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/Leon2Platform/tlmsrc/Leon2Platform.h +152 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/apbSubSystem/apbSubSystem.xml +429 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/apbSubSystem/designConfig_apbSubSystem.xml +64 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/apbSubSystem/design_apbSubSystem.xml +150 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/SystemTLM3/apbSubSystem/tlmsrc/apbSubSystem.h +167 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/ahbbus/1.4/ahbbus22.xml +236 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/ahbbus/1.4/tlmsrc/ahbbus.h +52 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/ahbram/1.4/ahbram.xml +184 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/ahbram/1.4/tlmsrc/ahbram.cc +93 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/ahbram/1.4/tlmsrc/ahbram.h +77 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbbus/1.4/apbbus8.xml +544 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbbus/1.4/tlmsrc/apbbus.h +55 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbmst/1.4/apbmst.xml +209 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbmst/1.4/tlmsrc/apbmst.h +53 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbram/1.0/apbram.xml +395 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbram/1.0/hdlsrc/apbram.cc +89 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbram/1.0/hdlsrc/apbram.h +69 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbram/1.0/hdlsrc/apbram.v +82 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/apbram/1.0/hdlsrc/apbram.vhd +132 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.4/cgu.xml +686 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.4/tlmsrc/cgu.cc +121 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.4/tlmsrc/cgu.h +81 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.5/cgu.xml +707 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.5/tlmsrc/cgu.cc +121 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/cgu/1.5/tlmsrc/cgu.h +81 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/dma/1.4/dma.xml +272 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/dma/1.4/tlmsrc/dma.cc +230 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/dma/1.4/tlmsrc/dma.h +116 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/irqctrl/1.4/irqctrl.xml +530 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/irqctrl/1.4/tlmsrc/irqctrl.cc +211 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/irqctrl/1.4/tlmsrc/irqctrl.h +108 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/processor/1.4/processor.xml +423 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/processor/1.4/tlmsrc/processor.cc +331 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/processor/1.4/tlmsrc/processor.h +121 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2apb/1.0/pv2apb.xml +240 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2apb/1.0/tlmsrc/pv2apb.cc +153 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2apb/1.0/tlmsrc/pv2apb.h +77 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2tac/1.0/pv2tac.xml +154 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2tac/1.0/tlmsrc/pv2tac.cc +114 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/pv2tac/1.0/tlmsrc/pv2tac.h +67 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/rgu/1.4/rgu.xml +766 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/rgu/1.4/tlmsrc/rgu.cc +126 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/rgu/1.4/tlmsrc/rgu.h +105 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/scmlAdaptor/1.0/scmlAdaptor.xml +154 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/scmlAdaptor/1.0/tlmsrc/scmladaptor.cc +100 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/scmlAdaptor/1.0/tlmsrc/scmladaptor.h +62 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/serial_device/1.0/serial_device.xml +151 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/serial_device/1.0/tlmsrc/serial_device.h +85 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/timers/1.4/timers.xml +460 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/timers/1.4/tlmsrc/timers.cc +201 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/timers/1.4/tlmsrc/timers.h +102 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/inc/uart.h +152 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/inc/uart_fifo.h +113 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/inc/uart_memory_map.h +96 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/inc/uart_types.h +60 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/src/uart.cc +125 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/src/uart_interrupt_handler.cc +136 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/src/uart_register_bank.cc +129 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/tlmsrc/src/uart_serial_tx_rx.cc +145 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_scml/1.0/uart_scml.xml +372 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/include/Leon2_uart.h +216 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/include/def_Leon2_uart.h +34 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/include/tlm_field.h +72 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/include/tlm_register.h +129 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/include/tlmreg_Leon2_uart.h +133 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/src/Leon2_uart.cc +316 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/src/tlmreg_Leon2_uart.cc +197 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/tlmsrc/src/user_specific_Leon2_uart.cc +146 -0
- data/spec/test_data/spiritconsortium.org/Leon2TLM/uart_tac/1.0/uart_tac.xml +222 -0
- data/spec/unit/component_spec.rb +98 -0
- data/spec/unit/graph_pathfinder_spec.rb +128 -0
- data/spec/unit/interconnect_spec.rb +177 -0
- data/spec/unit/ipxact_spec.rb +69 -0
- data/spec/unit/platform_spec.rb +34 -0
- metadata +225 -0
@@ -0,0 +1,235 @@
|
|
1
|
+
# Copyright (C) 2010 TIMA Laboratory
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
#
|
16
|
+
|
17
|
+
# {IPXACT::Component} is what an {IPXACT::Platform} is essentially made of.
|
18
|
+
# This class behaves like a Hash for general attributes (such as
|
19
|
+
# +:instance_name+, +:vendor+, +:name+ and +:version+). This class also defines
|
20
|
+
# 4 fixed attributes, that is: {#subcomponents}, {#interconnections},
|
21
|
+
# {#hierconnections} and {#ports}. While interconnections, hierconnections and
|
22
|
+
# ports are mostly used by the {IPXACT::GraphPathFinder} class, the
|
23
|
+
# subcomponents are what most users will be querying. Subcomponents may be
|
24
|
+
# terminal or non-terminal, i.e. composed of other subcomponents.
|
25
|
+
#
|
26
|
+
# @author Guillaume Godet-Bar
|
27
|
+
#
|
28
|
+
class IPXACT::Component < Hash
|
29
|
+
|
30
|
+
# @return [Array<Component>] the list of subcomponents
|
31
|
+
attr_accessor :subcomponents
|
32
|
+
|
33
|
+
# @return [Array<Hash>] the list of interconnections
|
34
|
+
attr_accessor :interconnections
|
35
|
+
|
36
|
+
# @return [Array<Hash>] the list of hierconnections
|
37
|
+
attr_accessor :hierconnections
|
38
|
+
|
39
|
+
# @return [Array<Hash>] the list of ports
|
40
|
+
attr_accessor :ports
|
41
|
+
|
42
|
+
# Creates a new {IPXACT::Component} instance
|
43
|
+
#
|
44
|
+
# @param [String] instance_name The name that will be used for identifying
|
45
|
+
# this specific component instance component.
|
46
|
+
# @param [String] name The name of the component type.
|
47
|
+
# @param [String] vendor The name of the component's vendor.
|
48
|
+
# @param [String] version The version of the component, following the typical
|
49
|
+
# relaxed semantic versioning convention +X(.Y(.Z)?)?+
|
50
|
+
#
|
51
|
+
def initialize(instance_name, name, vendor, version)
|
52
|
+
@subcomponents = {}
|
53
|
+
@interconnections = {}
|
54
|
+
@hierconnections = {}
|
55
|
+
@ports = []
|
56
|
+
self.merge!({:instance_name => instance_name,
|
57
|
+
:version => version,
|
58
|
+
:vendor => vendor,
|
59
|
+
:name => name})
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calculates an optimal path in the subcomponent graph between
|
63
|
+
# +subcomponent_start+ and +subcomponent_end+. This computation takes into
|
64
|
+
# account hierarchical subcomponents, and identifies optimal sub-paths in
|
65
|
+
# these elements as well, using hierconnections. This method is in fact the
|
66
|
+
# facade for the {IPXACT::GraphPathFinder} class. It handles the creation of
|
67
|
+
# the connection Hash, and translates the result in a IPXACT-specific format.
|
68
|
+
#
|
69
|
+
# @param [String] subcomponent_start The name of the component instance that
|
70
|
+
# should be the source of the data path.
|
71
|
+
# @param [String] subcomponent_end The name of the component instance that
|
72
|
+
# should be the target of the data path.
|
73
|
+
#
|
74
|
+
# @return [Array<Array<Hash>>] an Array of Arrays of Hashes that summarizes
|
75
|
+
# the component instances and the ports on the data path. Note that this
|
76
|
+
# data path may be used for calculating the target component's base
|
77
|
+
# address. The Arrays of Hashes are composed of 2 elements, the first
|
78
|
+
# element being the source of a connection step and the second element
|
79
|
+
# being the target of the connection step. Each element is a Hash, built as
|
80
|
+
# follows:
|
81
|
+
# +:component_instance+ the String name of the component instance that is
|
82
|
+
# traversed by the data path;
|
83
|
+
# +:port_name+ the String name of the port of the component instance that
|
84
|
+
# is being traversed.
|
85
|
+
# @raise several exceptions. Please refer to {IPXACT::GraphPathFinder} class
|
86
|
+
# for more details.
|
87
|
+
#
|
88
|
+
def resolve_data_path(subcomponent_start, subcomponent_end)
|
89
|
+
nodes, connections = rec_prepare_pathfinder_connections([], [])
|
90
|
+
|
91
|
+
pathfinder_connections = connections.collect do |connection|
|
92
|
+
{
|
93
|
+
:link => [nodes.index(connection[0][:component_instance]),
|
94
|
+
nodes.index(connection[1][:component_instance])],
|
95
|
+
:ports => [connection[0][:port_name], connection[1][:port_name]]
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
pathfinder_interconnect = {:nodes => nodes, :connections => pathfinder_connections}
|
100
|
+
pathfinder = IPXACT::GraphPathFinder.new(pathfinder_interconnect)
|
101
|
+
finder_result = pathfinder.resolve(subcomponent_start, subcomponent_end)
|
102
|
+
|
103
|
+
formatted_result = finder_result.collect do |res|
|
104
|
+
pathfinder_interconnect[:connections][res]
|
105
|
+
end.collect do |connection|
|
106
|
+
[
|
107
|
+
{
|
108
|
+
:component_instance => pathfinder_interconnect[:nodes][connection[:link][0]],
|
109
|
+
:port_name => connection[:ports][0]
|
110
|
+
},
|
111
|
+
{
|
112
|
+
:component_instance => pathfinder_interconnect[:nodes][connection[:link][1]],
|
113
|
+
:port_name => connection[:ports][1]
|
114
|
+
}
|
115
|
+
]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Computes a the base address of the last component instance mentionned in
|
120
|
+
# the +data_path+. The latter should be calculated using the
|
121
|
+
# {#resolve_data_path} method. Additionally, this method takes into account
|
122
|
+
# all subcomponents from the +data_path+, and basically adds up mirrored slave
|
123
|
+
# ports' remap addresses.
|
124
|
+
#
|
125
|
+
# @param [Arrray] data_path the data path from which the base address should be
|
126
|
+
# calculated. Please refer to the documentation of
|
127
|
+
# {#resolve_data_path} for more details on the structure of
|
128
|
+
# this argument.
|
129
|
+
# @param [Integer] initial_value the value that should be added to the base
|
130
|
+
# address computed by the method.
|
131
|
+
#
|
132
|
+
# Returns the base address of the target component, as an Integer.
|
133
|
+
#
|
134
|
+
def resolve_base_address(data_path, initial_value = 0)
|
135
|
+
base_address = initial_value
|
136
|
+
data_path.each do |connection|
|
137
|
+
connection.each do |connection_step|
|
138
|
+
subcomponent = rec_get_subcomponent(connection_step[:component_instance])
|
139
|
+
port = subcomponent.ports \
|
140
|
+
.select{|port| port[:name] == connection_step[:port_name]} \
|
141
|
+
.first
|
142
|
+
if port[:type] == :mirrored_slave && !port[:port_data].nil?
|
143
|
+
base_address += port[:port_data][:remap][:address].to_i(16)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
base_address
|
148
|
+
end
|
149
|
+
|
150
|
+
# Get the component's register map, if any.
|
151
|
+
#
|
152
|
+
# @return [Array] +nil+ if no register map could be found, or else an Array
|
153
|
+
# of registers (Hash) structured as follows:
|
154
|
+
# +:name+ the register's name;
|
155
|
+
# +:offset+ the register's offset (from the memory map's base address,
|
156
|
+
# expressed as a hex String value);
|
157
|
+
# +:size+ the register's size (in bits, expressed as a String);
|
158
|
+
# +:access+ the register's access (read-write, read-only, write-only etc.),
|
159
|
+
# expressed as a String.
|
160
|
+
#
|
161
|
+
def register_map
|
162
|
+
return nil \
|
163
|
+
unless ports.any?{|port| port[:type] == :slave} ||
|
164
|
+
ports.any?{|port| port[:port_data][:registers]}
|
165
|
+
|
166
|
+
ports.select{|port| port[:type] == :slave && port[:port_data][:registers]} \
|
167
|
+
.first[:port_data][:registers]
|
168
|
+
end
|
169
|
+
|
170
|
+
# Commodity method for getting a component instance called +instance_name+,
|
171
|
+
# either from the direct subcomponents of the component, or from the
|
172
|
+
# subcomponents hierarchy.
|
173
|
+
#
|
174
|
+
# @param [String] instance_name the name of the subcomponent instance.
|
175
|
+
#
|
176
|
+
# @return [Component] the subcomponent instance or nil if none could be found.
|
177
|
+
#
|
178
|
+
def rec_get_subcomponent(instance_name)
|
179
|
+
if subcomponents.has_key?(instance_name)
|
180
|
+
subcomponents[instance_name]
|
181
|
+
elsif subcomponents.empty?
|
182
|
+
nil
|
183
|
+
else
|
184
|
+
subcomponents.collect{|sub_name, sub| sub.rec_get_subcomponent(instance_name)} \
|
185
|
+
.compact.first
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Prepares the connection structure for the {IPXACT::GraphPathFinder} class.
|
190
|
+
# Traverses the hierarchy of subcomponents in order to create a flattened
|
191
|
+
# representation of the subcomponents graph. In particular, the method
|
192
|
+
# considers hierconnections, and replaces the wrapper's interface port with
|
193
|
+
# the subcomponent's port that it is attached to.
|
194
|
+
#
|
195
|
+
# @return [Array<Array,Array<Hash>>] an Array of 2 elements, composed of a
|
196
|
+
# list of nodes and a list of connections. Please refer to the
|
197
|
+
# {IPXACT::GraphPathFinder#initialize} method for more details on
|
198
|
+
# the structure of these elements (both Hashes).
|
199
|
+
#
|
200
|
+
def rec_prepare_pathfinder_connections(current_nodes, current_interconnections)
|
201
|
+
if subcomponents.empty?
|
202
|
+
[current_nodes << self[:instance_name], current_interconnections]
|
203
|
+
else
|
204
|
+
subcomponents.each do |sub_name, subcomponent|
|
205
|
+
formatted_interconnections = interconnections.values.collect do |interconnect|
|
206
|
+
[reformat_connector(interconnect[0]), reformat_connector(interconnect[1])]
|
207
|
+
end
|
208
|
+
current_nodes, current_interconnections = \
|
209
|
+
subcomponent.rec_prepare_pathfinder_connections(current_nodes, current_interconnections + formatted_interconnections)
|
210
|
+
end
|
211
|
+
[current_nodes, current_interconnections]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Executes the actual replacement of an hierarchical component's outside port
|
216
|
+
# with the attached subcomponent port.
|
217
|
+
#
|
218
|
+
# @return [Hash] the flattened connector, i.e., a Hash built as follows:
|
219
|
+
# +:component_instance+ the String name of the component instance that is
|
220
|
+
# traversed by the data path;
|
221
|
+
# +:port_name+ the String name of the port of the component
|
222
|
+
# instance that is being traversed.
|
223
|
+
#
|
224
|
+
def reformat_connector(connector)
|
225
|
+
instance = subcomponents[connector[:component_instance]]
|
226
|
+
if instance.subcomponents.empty?
|
227
|
+
new_connector = connector
|
228
|
+
else
|
229
|
+
port = connector[:port_name]
|
230
|
+
new_connector = instance.hierconnections[port]
|
231
|
+
end
|
232
|
+
new_connector
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (C) 2010 TIMA Laboratory
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
#
|
16
|
+
|
17
|
+
# Root module for the parser submodules.
|
18
|
+
#
|
19
|
+
# @author Guillaume Godet-Bar
|
20
|
+
#
|
21
|
+
module IPXACT::Parser
|
22
|
+
end
|
23
|
+
|
24
|
+
require File.join File.dirname(__FILE__), 'parser/bus_data_parser'
|
25
|
+
require File.join File.dirname(__FILE__), 'parser/component_data_parser'
|
26
|
+
require File.join File.dirname(__FILE__), 'parser/platform_data_parser'
|
27
|
+
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# Copyright (C) 2010 TIMA Laboratory
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
#
|
16
|
+
|
17
|
+
# Module for parsing IPXACT bus XML data.
|
18
|
+
#
|
19
|
+
# @author Guillaume Godet-Bar
|
20
|
+
#
|
21
|
+
module IPXACT::Parser::BusData
|
22
|
+
|
23
|
+
# Parses the bus_doc bus interface data.
|
24
|
+
#
|
25
|
+
# @param [Nokogiri::Node] bus_doc the bus interface's IPXACT excerpt.
|
26
|
+
# @param [Nokogiri::Node] host_component the bus interface's host component
|
27
|
+
# IPXACT excerpt.
|
28
|
+
# @param [Array] variables the list of variables that are associated to the host
|
29
|
+
# component instance.
|
30
|
+
#
|
31
|
+
# @return [Hash] a Hash that describes the bus interface element. This Hash is
|
32
|
+
# composed of:
|
33
|
+
# :name - The name of the port.
|
34
|
+
# :type - The port type (i.e., :master, :mirrored_master, :slave or
|
35
|
+
# :mirrored_slave)
|
36
|
+
# :bus_type - The bus interface type (i.e., its generic name).
|
37
|
+
# :library - The library in which the bus interface is defined.
|
38
|
+
# :port_data - Specific port data, depending on the port type.
|
39
|
+
#
|
40
|
+
def self.parse_bus(bus_doc, host_component, variables)
|
41
|
+
port_type, port_data = extract_bus_data(bus_doc, host_component, variables)
|
42
|
+
|
43
|
+
{
|
44
|
+
:name => bus_doc.xpath("./spirit:name").first.text,
|
45
|
+
:type => port_type,
|
46
|
+
:bus_type => bus_doc.xpath("./spirit:busType").first['name'],
|
47
|
+
:library => bus_doc.xpath("./spirit:busType").first['library'],
|
48
|
+
:port_data => port_data
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Extracts any relevant data from the bus_doc bus interface.
|
53
|
+
#
|
54
|
+
# @param [Nokogiri::Node] bus_doc the bus interface's IPXACT excerpt.
|
55
|
+
# @param [Nokogiri::Node] host_component the bus interface's host component
|
56
|
+
# IPXACT excerpt (i.e., Nokogiri Node).
|
57
|
+
# @param [Array<Hash>] variables the list of variables that are associated
|
58
|
+
# to the host component instance.
|
59
|
+
#
|
60
|
+
# @return [Array<Symbol, Object>] an Array with the first element being the
|
61
|
+
# port type (i.e., +:master+, +:mirrored_master+, +:slave+ or
|
62
|
+
# +:mirrored_slave+), and the second element being +nil+, a Hash, or an
|
63
|
+
# Array of Hashes, depending on the bus interface's type.
|
64
|
+
#
|
65
|
+
def self.extract_bus_data(bus_doc, host_component, variables)
|
66
|
+
if bus_doc.xpath("./spirit:mirroredMaster").size > 0
|
67
|
+
[:mirrored_master, extract_mirrored_master_data]
|
68
|
+
elsif bus_doc.xpath("./spirit:mirroredSlave").size > 0
|
69
|
+
[:mirrored_slave, extract_mirrored_slave_data(bus_doc, host_component, variables)]
|
70
|
+
elsif bus_doc.xpath("./spirit:slave").size > 0
|
71
|
+
[:slave, extract_slave_data(bus_doc, host_component)]
|
72
|
+
elsif bus_doc.xpath("./spirit:master").size > 0
|
73
|
+
[:master, extract_master_data(bus_doc, host_component)]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Extracts all relevant data from a master bus interface (i.e., the address
|
81
|
+
# space's range and width, if any).
|
82
|
+
#
|
83
|
+
# @param [Nokogiri::Node] bus_doc the bus interface's IPXACT excerpt.
|
84
|
+
# @param [Nokogiri::Node] host_component the bus interface's host component
|
85
|
+
# IPXACT excerpt (i.e., Nokogiri Node).
|
86
|
+
#
|
87
|
+
# @return +nil+ if no address space can be found or else a Hash
|
88
|
+
# composed of:
|
89
|
+
# :address_space_name - The address space's name.
|
90
|
+
# :range - The address space's range.
|
91
|
+
# :width - The address space's width.
|
92
|
+
#
|
93
|
+
def self.extract_master_data(bus_doc, host_component)
|
94
|
+
address_space_ref = bus_doc.xpath("./spirit:master/spirit:addressSpaceRef")
|
95
|
+
if address_space_ref.size > 0
|
96
|
+
address_space = host_component.xpath(".//spirit:addressSpace") \
|
97
|
+
.select do |as|
|
98
|
+
as.xpath("./spirit:name").first.text \
|
99
|
+
== address_space_ref.first['addressSpaceRef']
|
100
|
+
end.first
|
101
|
+
address_space_data = {
|
102
|
+
:address_space_name => address_space_ref.first['addressSpaceRef'],
|
103
|
+
:range => address_space.xpath("./spirit:range").first.text,
|
104
|
+
:width => address_space.xpath("./spirit:width").first.text
|
105
|
+
}
|
106
|
+
end
|
107
|
+
address_space_data
|
108
|
+
end
|
109
|
+
|
110
|
+
# Extracts all relevant data from a mirrored master bus interface.
|
111
|
+
#
|
112
|
+
# @return +nil+
|
113
|
+
#
|
114
|
+
def self.extract_mirrored_master_data
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
|
118
|
+
# Extracts all relevant data from a mirrored slave interface (i.e., remap
|
119
|
+
# address and range), and applies any relevant variable value on the
|
120
|
+
# extracted bus data.
|
121
|
+
#
|
122
|
+
# @param [Nokogiri::Node] bus_doc the bus interface's IPXACT excerpt.
|
123
|
+
# @param [Nokogiri::Node] host_component the bus interface's host component
|
124
|
+
# IPXACT excerpt (i.e., Nokogiri Node).
|
125
|
+
# @param [Array<Hash>] variables the list of variables that are associated to
|
126
|
+
# the host component instance.
|
127
|
+
#
|
128
|
+
# @return [Hash] a Hash constructed as
|
129
|
+
# follows:
|
130
|
+
# :remap - A Hash composed of the remap address value (+:address+), and its
|
131
|
+
# associated identifier (for variable application).
|
132
|
+
# :range - A Hash composed of the address range value (+:value+), and its
|
133
|
+
# associated identifier (for variable application).
|
134
|
+
#
|
135
|
+
def self.extract_mirrored_slave_data(bus_doc, host_component, variables)
|
136
|
+
component_name = host_component.xpath("./spirit:component/spirit:name").first.text
|
137
|
+
|
138
|
+
base_addresses = bus_doc.xpath("./spirit:mirroredSlave/spirit:baseAddresses")
|
139
|
+
if base_addresses.size > 0
|
140
|
+
|
141
|
+
bus_data = {
|
142
|
+
:remap => {
|
143
|
+
:address => base_addresses.first.xpath("./spirit:remapAddress").first.text,
|
144
|
+
:id => base_addresses.first.xpath("./spirit:remapAddress").first['id']
|
145
|
+
},
|
146
|
+
:range => {
|
147
|
+
:value => base_addresses.first.xpath("./spirit:range").first.text,
|
148
|
+
:id => base_addresses.first.xpath("./spirit:range").first['id']
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
unless variables.empty?
|
153
|
+
variables.each do |var_key, var_value|
|
154
|
+
if bus_data[:remap][:id] == var_key
|
155
|
+
bus_data[:remap][:address] = var_value
|
156
|
+
elsif bus_data[:range][:id] == var_key
|
157
|
+
bus_data[:range][:value] = var_value
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
bus_data
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Extracts all relevant data from a slave bus interface (i.e., its first
|
167
|
+
# memory map, and associated address block data, such as the block's base
|
168
|
+
# address, range, etc., and its register map).
|
169
|
+
#
|
170
|
+
# @param [Nokogiri::Node] bus_doc the bus interface's IPXACT excerpt.
|
171
|
+
# @param [Nokogiri:: Node] host_component the bus interface's host component
|
172
|
+
# IPXACT excerpt (i.e., Nokogiri Node).
|
173
|
+
#
|
174
|
+
# @return [Hash] a Hash representing the bus interface's memory map, composed as
|
175
|
+
# follows:
|
176
|
+
# :memory_map_name - The memory map's name String.
|
177
|
+
# :base_address - The memory map's base address (if any) hex String.
|
178
|
+
# :range - The memory map's range (if any) decimal String.
|
179
|
+
# :width - The memory map's width (if any) decimal String.
|
180
|
+
# :registers - The memory map's registers (if any), which are
|
181
|
+
# composed of:
|
182
|
+
# :name - The register's name.
|
183
|
+
# :offset - The register's offset (from the memory
|
184
|
+
# map's base address, expressed as a hex
|
185
|
+
# String value).
|
186
|
+
# :size - The register's size (in bits, expressed as
|
187
|
+
# a String).
|
188
|
+
# :access - The register's access (read-write,
|
189
|
+
# read-only, write-only etc.), expressed as
|
190
|
+
# a String.
|
191
|
+
#
|
192
|
+
def self.extract_slave_data(bus_doc, host_component)
|
193
|
+
memory_map_ref = bus_doc.xpath("./spirit:slave/spirit:memoryMapRef")
|
194
|
+
unless memory_map_ref.empty?
|
195
|
+
memory_map = host_component.xpath(".//spirit:memoryMap") \
|
196
|
+
.select do |mm|
|
197
|
+
mm.xpath("./spirit:name").text \
|
198
|
+
== memory_map_ref.first['memoryMapRef']
|
199
|
+
end.first
|
200
|
+
|
201
|
+
address_block = memory_map.xpath("./spirit:addressBlock[1]")
|
202
|
+
unless address_block.empty?
|
203
|
+
|
204
|
+
registers_doc = address_block.xpath("./spirit:register")
|
205
|
+
registers = registers_doc.collect do |register_doc|
|
206
|
+
{
|
207
|
+
:name => register_doc.xpath("./spirit:name").text,
|
208
|
+
:offset => register_doc.xpath("./spirit:addressOffset").text,
|
209
|
+
:size => register_doc.xpath("./spirit:size").text,
|
210
|
+
:access => register_doc.xpath("./spirit:access").text
|
211
|
+
}
|
212
|
+
end
|
213
|
+
|
214
|
+
address_block_data = {
|
215
|
+
:base_address => address_block.xpath("./spirit:baseAddress").text,
|
216
|
+
:range => address_block.xpath("./spirit:range").text,
|
217
|
+
:width => address_block.xpath("./spirit:width").text,
|
218
|
+
:registers => registers
|
219
|
+
}
|
220
|
+
end
|
221
|
+
memory_map_data = {
|
222
|
+
:memory_map_name => memory_map.xpath("./spirit:name").text
|
223
|
+
}
|
224
|
+
end
|
225
|
+
memory_map_data.merge!(address_block_data || {}) unless memory_map_data.nil?
|
226
|
+
|
227
|
+
memory_map_data
|
228
|
+
end
|
229
|
+
end
|