Class: IPXACT::Component

Inherits:
Hash
  • Object
show all
Defined in:
lib/ipxact/component.rb

Overview

Component is what an Platform is essentially made of. This class behaves like a Hash for general attributes (such as :instance_name, :vendor, :name and :version). This class also defines 4 fixed attributes, that is: #subcomponents, #interconnections, #hierconnections and #ports. While interconnections, hierconnections and ports are mostly used by the GraphPathFinder class, the subcomponents are what most users will be querying. Subcomponents may be terminal or non-terminal, i.e. composed of other subcomponents.

Author:

  • Guillaume Godet-Bar

Direct Known Subclasses

Platform

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instance_name, name, vendor, version) ⇒ Component

Creates a new IPXACT::Component instance

Parameters:

  • instance_name (String)

    The name that will be used for identifying this specific component instance component.

  • name (String)

    The name of the component type.

  • vendor (String)

    The name of the component’s vendor.

  • version (String)

    The version of the component, following the typical relaxed semantic versioning convention X(.Y(.Z)?)?



51
52
53
54
55
56
57
58
59
60
# File 'lib/ipxact/component.rb', line 51

def initialize(instance_name, name, vendor, version)
  @subcomponents = {}
  @interconnections = {}
  @hierconnections = {}
  @ports = []
  self.merge!({:instance_name => instance_name,
               :version => version,
               :vendor => vendor,
               :name => name})
end

Instance Attribute Details

#hierconnectionsArray<Hash>

Returns the list of hierconnections.

Returns:

  • (Array<Hash>)

    the list of hierconnections



37
38
39
# File 'lib/ipxact/component.rb', line 37

def hierconnections
  @hierconnections
end

#interconnectionsArray<Hash>

Returns the list of interconnections.

Returns:

  • (Array<Hash>)

    the list of interconnections



34
35
36
# File 'lib/ipxact/component.rb', line 34

def interconnections
  @interconnections
end

#portsArray<Hash>

Returns the list of ports.

Returns:

  • (Array<Hash>)

    the list of ports



40
41
42
# File 'lib/ipxact/component.rb', line 40

def ports
  @ports
end

#subcomponentsArray<Component>

Returns the list of subcomponents.

Returns:

  • (Array<Component>)

    the list of subcomponents



31
32
33
# File 'lib/ipxact/component.rb', line 31

def subcomponents
  @subcomponents
end

Instance Method Details

#rec_get_subcomponent(instance_name) ⇒ Component

Commodity method for getting a component instance called instance_name, either from the direct subcomponents of the component, or from the subcomponents hierarchy.

Parameters:

  • instance_name (String)

    the name of the subcomponent instance.

Returns:

  • (Component)

    the subcomponent instance or nil if none could be found.



178
179
180
181
182
183
184
185
186
187
# File 'lib/ipxact/component.rb', line 178

def rec_get_subcomponent(instance_name)
  if subcomponents.has_key?(instance_name)
    subcomponents[instance_name]
  elsif subcomponents.empty?
    nil
  else
    subcomponents.collect{|sub_name, sub| sub.rec_get_subcomponent(instance_name)} \
                 .compact.first
  end
end

#rec_prepare_pathfinder_connections(current_nodes, current_interconnections) ⇒ Array<Array,Array<Hash>>

Prepares the connection structure for the GraphPathFinder class. Traverses the hierarchy of subcomponents in order to create a flattened representation of the subcomponents graph. In particular, the method considers hierconnections, and replaces the wrapper’s interface port with the subcomponent’s port that it is attached to.

Returns:

  • (Array<Array,Array<Hash>>)

    an Array of 2 elements, composed of a list of nodes and a list of connections. Please refer to the GraphPathFinder#initialize method for more details on the structure of these elements (both Hashes).



200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/ipxact/component.rb', line 200

def rec_prepare_pathfinder_connections(current_nodes, current_interconnections)
  if subcomponents.empty?
    [current_nodes << self[:instance_name], current_interconnections]
  else
    subcomponents.each do |sub_name, subcomponent|
      formatted_interconnections = interconnections.values.collect do |interconnect|
        [reformat_connector(interconnect[0]), reformat_connector(interconnect[1])]
      end
      current_nodes, current_interconnections = \
        subcomponent.rec_prepare_pathfinder_connections(current_nodes, current_interconnections + formatted_interconnections)
    end
    [current_nodes, current_interconnections]
  end
end

#reformat_connector(connector) ⇒ Hash

Executes the actual replacement of an hierarchical component’s outside port with the attached subcomponent port.

Returns:

  • (Hash)

    the flattened connector, i.e., a Hash built as follows: :component_instance the String name of the component instance that is traversed by the data path; :port_name the String name of the port of the component instance that is being traversed.



224
225
226
227
228
229
230
231
232
233
# File 'lib/ipxact/component.rb', line 224

def reformat_connector(connector)
  instance = subcomponents[connector[:component_instance]]
  if instance.subcomponents.empty?
    new_connector = connector
  else
    port = connector[:port_name]
    new_connector = instance.hierconnections[port]
  end
  new_connector
end

#register_mapArray

Get the component’s register map, if any.

Returns:

  • (Array)

    nil if no register map could be found, or else an Array of registers (Hash) structured as follows: :name the register’s name; :offset the register’s offset (from the memory map’s base address, expressed as a hex String value); :size the register’s size (in bits, expressed as a String); :access the register’s access (read-write, read-only, write-only etc.), expressed as a String.



161
162
163
164
165
166
167
168
# File 'lib/ipxact/component.rb', line 161

def register_map
  return nil \
    unless ports.any?{|port| port[:type] == :slave} ||
           ports.any?{|port| port[:port_data][:registers]}

    ports.select{|port| port[:type] == :slave && port[:port_data][:registers]} \
         .first[:port_data][:registers]
end

#resolve_base_address(data_path, initial_value = 0) ⇒ Object

Computes a the base address of the last component instance mentionned in the data_path. The latter should be calculated using the #resolve_data_path method. Additionally, this method takes into account all subcomponents from the data_path, and basically adds up mirrored slave ports’ remap addresses.

Returns the base address of the target component, as an Integer.

Parameters:

  • data_path (Arrray)

    the data path from which the base address should be calculated. Please refer to the documentation of #resolve_data_path for more details on the structure of this argument.

  • initial_value (Integer) (defaults to: 0)

    the value that should be added to the base address computed by the method.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/ipxact/component.rb', line 134

def resolve_base_address(data_path, initial_value = 0)
  base_address = initial_value
  data_path.each do |connection|
    connection.each do |connection_step|
      subcomponent = rec_get_subcomponent(connection_step[:component_instance])
      port = subcomponent.ports \
                .select{|port| port[:name] == connection_step[:port_name]} \
                .first
      if port[:type] == :mirrored_slave && !port[:port_data].nil?
        base_address += port[:port_data][:remap][:address].to_i(16)
      end
    end
  end
  base_address
end

#resolve_data_path(subcomponent_start, subcomponent_end) ⇒ Array<Array<Hash>>

Calculates an optimal path in the subcomponent graph between subcomponent_start and subcomponent_end. This computation takes into account hierarchical subcomponents, and identifies optimal sub-paths in these elements as well, using hierconnections. This method is in fact the facade for the GraphPathFinder class. It handles the creation of the connection Hash, and translates the result in a IPXACT-specific format.

Parameters:

  • subcomponent_start (String)

    The name of the component instance that should be the source of the data path.

  • subcomponent_end (String)

    The name of the component instance that should be the target of the data path.

Returns:

  • (Array<Array<Hash>>)

    an Array of Arrays of Hashes that summarizes the component instances and the ports on the data path. Note that this data path may be used for calculating the target component’s base address. The Arrays of Hashes are composed of 2 elements, the first element being the source of a connection step and the second element being the target of the connection step. Each element is a Hash, built as follows: :component_instance the String name of the component instance that is traversed by the data path; :port_name the String name of the port of the component instance that is being traversed.

Raises:

  • several exceptions. Please refer to GraphPathFinder class for more details.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ipxact/component.rb', line 88

def resolve_data_path(subcomponent_start, subcomponent_end)
  nodes, connections = rec_prepare_pathfinder_connections([], [])

  pathfinder_connections = connections.collect do |connection|
    {
      :link => [nodes.index(connection[0][:component_instance]),
                nodes.index(connection[1][:component_instance])],
      :ports => [connection[0][:port_name], connection[1][:port_name]]
    }
  end

  pathfinder_interconnect = {:nodes => nodes, :connections => pathfinder_connections}
  pathfinder = IPXACT::GraphPathFinder.new(pathfinder_interconnect)
  finder_result = pathfinder.resolve(subcomponent_start, subcomponent_end)

  formatted_result = finder_result.collect do |res|
    pathfinder_interconnect[:connections][res]
  end.collect do |connection|
    [
      {
        :component_instance => pathfinder_interconnect[:nodes][connection[:link][0]],
        :port_name => connection[:ports][0]
      },
      {
        :component_instance => pathfinder_interconnect[:nodes][connection[:link][1]],
        :port_name => connection[:ports][1]
      }
    ]
  end
end