Commit 697af5ff authored by Maxime Perrotin's avatar Maxime Perrotin

Fix end-to-end connections in deployment view

in nested systems, the deployment view is not directly reflecting end to
end conections on the bus connection bindings.
parent ff9184fa
......@@ -191,6 +191,7 @@ package body TASTE.AADL_Parser is
then
AADL_Lib.Append (Result.Configuration.Interface_View.Element);
Result.Deployment_View := Parse_Deployment_View (Deployment_Root);
Result.Deployment_View.Fix_Bus_Connections (Result.Interface_View);
end if;
end if;
......
......@@ -574,7 +574,7 @@ package body TASTE.Concurrency_View is
-- directly provide the partition name of the function so we have
-- to retrieve it here
for BC : Bus_Connection of CV.Deployment.Connections loop
Connect_Via_Bus := Connect_Via_Bus & BC.Bus_Name;
Connect_Via_Bus := Connect_Via_Bus & BC.Bus_Name;
Connect_Port_Name := Connect_Port_Name & BC.Source_Port;
Found := False;
for Node of CV.Deployment.Nodes loop
......@@ -582,7 +582,7 @@ package body TASTE.Concurrency_View is
for Part of Node.Partitions loop
exit when Found;
if Part.Bound_Functions.Contains
(To_String (BC.Source_Function)) -- Dest_Function))
(To_String (BC.Source_Function))
then
Connect_From_Partition :=
Connect_From_Partition & Part.Name;
......@@ -593,7 +593,7 @@ package body TASTE.Concurrency_View is
if not Found then
raise Concurrency_View_Error with
"Could not find partition of function "
& To_String (BC.Source_Function); -- Dest_Function);
& To_String (BC.Source_Function);
end if;
end loop;
......
......@@ -162,9 +162,15 @@ package body TASTE.Deployment_View is
SRC_FUNCTION := US (Get_Name_String
(Name (Identifier
(Parent_Subcomponent
(Parent_Component (SRC))))));
(Parent_Component (SRC))))));
-- The source and destination function/ports are irrelevant
-- here because they may not be end-to-end connections in
-- case of a hierarchical structure. All bus connections
-- must be updated before processing the concurrency view, but
-- this can be done only using the interface view information.
Result := Result
& Bus_Connection'(Dest_Port => DST_PORT,
& Bus_Connection'(Channel_Name => US (AIN_Case (Conn)),
Dest_Port => DST_PORT,
Dest_Function => DST_FUNCTION,
Bus_Name =>
US (Get_Name_String (Bound_Bus_Name)),
......@@ -641,6 +647,33 @@ package body TASTE.Deployment_View is
return Option_Partition.Nothing;
end Find_Partition;
procedure Fix_Bus_Connections (DV : in out Complete_Deployment_View;
IV : Complete_Interface_View) is
begin
-- We must find the channel referenced in the bus connection
-- among all the connections of the interface view to retrieve
-- the end-to-end connections and set the source/dest port properly,
-- i.e. not referencing any nesting functions (which are not mapped
-- to any partition)
for C_DV : Bus_Connection of DV.Connections loop
for C_IV : Connection of IV.Connections loop
for Channel of C_IV.Channels loop
if Channel = C_DV.Channel_Name then
Put_Debug ("End to end: " & To_String (C_IV.Caller)
& "." & To_String (C_IV.RI_Name)
& " -> " & To_String (C_IV.Callee)
& "." & To_String (C_IV.PI_Name));
-- Update the information in the deployment view
C_DV.Source_Function := C_IV.Caller;
C_DV.Source_Port := C_IV.RI_Name;
C_DV.Dest_Function := C_IV.Callee;
C_DV.Dest_Port := C_IV.PI_Name;
end if;
end loop;
end loop;
end loop;
end Fix_Bus_Connections;
procedure Dump_Nodes (DV : Complete_Deployment_View; Output : File_Type) is
begin
for Each of DV.Nodes loop
......
......@@ -14,7 +14,8 @@ with Ada.Containers.Indefinite_Ordered_Maps,
Ocarina.Types,
Ocarina.Backends.Properties,
Option_Type,
TASTE.Parser_Utils;
TASTE.Parser_Utils,
TASTE.Interface_View;
use Ada.Containers,
Ada.Strings.Unbounded,
......@@ -23,7 +24,8 @@ use Ada.Containers,
Ocarina,
Ocarina.Types,
Ocarina.Backends.Properties,
TASTE.Parser_Utils;
TASTE.Parser_Utils,
TASTE.Interface_View;
package TASTE.Deployment_View is
......@@ -71,6 +73,7 @@ package TASTE.Deployment_View is
type Bus_Connection is tagged
record
Channel_Name,
Source_Function,
Source_Port,
Bus_Name,
......@@ -204,7 +207,12 @@ package TASTE.Deployment_View is
-- Function to build up the Ada AST by transforming the one from Ocarina
function Parse_Deployment_View (System : Node_Id)
return Complete_Deployment_View
with Pre => System /= No_Node;
with Pre => System /= No_Node;
-- Replace bus connection ports with end-to-end connections
procedure Fix_Bus_Connections (DV : in out Complete_Deployment_View;
IV : Complete_Interface_View);
procedure Dump_Nodes (DV : Complete_Deployment_View;
Output : File_Type);
procedure Dump_Connections (DV : Complete_Deployment_View;
......
......@@ -303,6 +303,10 @@ package body TASTE.Interface_View is
-- Parse a connection
function Parse_Connection (Conn : Node_Id) return Optional_Connection is
use Option_Connection;
use String_Vectors;
Channel_Name : constant String := AIN_Case (Conn);
Channels : String_Vectors.Vector := String_Vectors.Empty_Vector;
Caller : constant Node_Id := AIN.Item (AIN.First_Node
(AIN.Path (AIN.Destination (Conn))));
Callee : constant Node_Id := AIN.Item (AIN.First_Node
......@@ -328,16 +332,22 @@ package body TASTE.Interface_View is
end if;
PI_Name := Get_Interface_Name
(Get_Referenced_Entity (AIN.Source (Conn)));
return Just (Connection'(Caller =>
(if Kind (Caller) = K_Subcomponent_Access_Instance then US ("_env")
else US (AIN_Case (Caller))),
Callee =>
(if Kind (Callee) = K_Subcomponent_Access_Instance then US ("_env")
else US (AIN_Case (Callee))),
PI_Name => US (Get_Name_String (PI_Name)),
RI_Name => US (Get_Name_String (RI_Name))));
(Get_Referenced_Entity (AIN.Source (Conn)));
Channels := Channels & Channel_Name;
return Just (Connection'(
Channels => Channels,
Caller =>
(if Kind (Caller) = K_Subcomponent_Access_Instance
then US ("_env")
else US (AIN_Case (Caller))),
Callee =>
(if Kind (Callee) = K_Subcomponent_Access_Instance
then US ("_env")
else US (AIN_Case (Callee))),
PI_Name => US (Get_Name_String (PI_Name)),
RI_Name => US (Get_Name_String (RI_Name))));
end Parse_Connection;
-- Create a vector of connections for a given system
......@@ -471,8 +481,11 @@ package body TASTE.Interface_View is
-- Recursive function making jumps to find the provided interface
-- connected to a required interface. It returns a Remote Entity,
-- which contains the name of the remote PI and the name of the function
function Rec_Jump (From : String; RI : String;
Going_Out : Boolean := False) return Remote_Entity is
function Rec_Jump (From, RI : String;
Going_Out : Boolean := False;
Via_Channels : in out String_Vectors.Vector)
return Remote_Entity is
use String_Vectors;
Context : constant String :=
(if Functions.Contains (Key => From)
then To_String (Functions.Element (Key => From).Context)
......@@ -500,16 +513,18 @@ package body TASTE.Interface_View is
if Each.Callee = "_env" then
Set_Going_Out := True;
end if;
Via_Channels := Via_Channels & Each.Channels;
Result :=
(if Functions.Contains (Key => To_String (Each.Callee))
then (Function_Name => Each.Callee,
Interface_Name => Each.PI_Name)
else Rec_Jump (From => (if not Set_Going_Out
then To_String (Each.Callee)
else Context),
Going_Out => Set_Going_Out,
RI => To_String (Each.PI_Name)));
else Rec_Jump (From => (if not Set_Going_Out
then To_String (Each.Callee)
else Context),
Going_Out => Set_Going_Out,
RI => To_String (Each.PI_Name),
Via_Channels => Via_Channels));
end if;
exit when Each.Caller = Source and Each.RI_Name = US (RI);
......@@ -707,10 +722,13 @@ package body TASTE.Interface_View is
for Each of Functions loop
for RI of Each.Required loop
declare
Via_Channels : String_Vectors.Vector;
-- From a RI, follow the connection until the remote PI
-- Update list of visited channels on the spot
Remote : constant Remote_Entity := Rec_Jump
(To_String (Each.Name),
To_String (RI.Name));
(To_String (Each.Name),
To_String (RI.Name),
Via_Channels => Via_Channels);
begin
if Remote.Function_Name /= "Not found!" then
RI.Remote_Interfaces.Append (Remote);
......@@ -722,10 +740,11 @@ package body TASTE.Interface_View is
-- Update list of end to end connections with RI->PI
End_To_End_Connections := End_To_End_Connections
& (Caller => Each.Name,
Callee => Remote.Function_Name,
RI_Name => RI.Name,
PI_Name => Remote.Interface_Name);
& (Channels => Via_Channels,
Caller => Each.Name,
Callee => Remote.Function_Name,
RI_Name => RI.Name,
PI_Name => Remote.Interface_Name);
end if;
end;
end loop;
......@@ -739,10 +758,11 @@ package body TASTE.Interface_View is
-- Add periodic PIs to the list of connections
if PI.RCM = Cyclic_Operation and not Each.Is_Type then
End_To_End_Connections := End_To_End_Connections
& (Caller => US ("ENV"),
Callee => Each.Name,
RI_Name => PI.Name,
PI_Name => PI.Name);
& (Channels => String_Vectors.Empty_Vector,
Caller => US ("ENV"),
Callee => Each.Name,
RI_Name => PI.Name,
PI_Name => PI.Name);
end if;
for Fn of Functions loop
......@@ -761,6 +781,16 @@ package body TASTE.Interface_View is
end loop;
end loop;
-- Debug: check end-to-end connection paths
-- for C of End_To_End_Connections loop
-- Put_Debug ("From " & To_String (C.Caller) & "."
-- & To_String (C.RI_Name) & " to " & To_String (C.Callee)
-- & "." & To_String (C.PI_Name) & " via ...");
-- for P of C.Channels loop
-- Put_Debug ("... " & P);
-- end loop;
-- end loop;
return IV_AST : constant Complete_Interface_View :=
(Flat_Functions => Functions,
Connections => End_To_End_Connections);
......
......@@ -160,10 +160,12 @@ package TASTE.Interface_View is
type Connection is
record
Caller : Unbounded_String;
Callee : Unbounded_String;
RI_Name : Unbounded_String;
Caller,
Callee,
RI_Name,
PI_Name : Unbounded_String;
-- Channels: list of channels needed to go from RI to PI
Channels : String_Vectors.Vector;
end record;
package Option_Connection is new Option_Type (Connection);
......
KAZOO=../../kazoo
all: test-parse
cd output && make
$(MAKE) -C work
generate:
$(KAZOO) --gw \
-o output \
--glue \
--debug
-p \
-o work \
--glue \
--debug
test-parse: clean generate
clean:
rm -rf output
rm -rf work
.PHONY: clean test-parse
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment