ipxact-ruby 0.11.1
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.
- 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
|