aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/elab-vhdl_expr.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/elab-vhdl_expr.adb')
-rw-r--r--src/synth/elab-vhdl_expr.adb89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb
index ee15c7e52..cb5e7a26d 100644
--- a/src/synth/elab-vhdl_expr.adb
+++ b/src/synth/elab-vhdl_expr.adb
@@ -37,6 +37,7 @@ with Synth.Errors; use Synth.Errors;
with Grt.Types;
with Grt.To_Strings;
+with Grt.Vstrings;
package body Elab.Vhdl_Expr is
function Synth_Bounds_From_Length (Atype : Node; Len : Int32)
@@ -420,4 +421,92 @@ package body Elab.Vhdl_Expr is
return Res;
end Exec_String_Literal;
+ function Exec_Path_Instance_Name_Attribute
+ (Inst : Synth_Instance_Acc; Attr : Iir) return Memtyp
+ is
+ use Grt.Vstrings;
+ use Name_Table;
+
+ Is_Instance : constant Boolean :=
+ Get_Kind (Attr) = Iir_Kind_Instance_Name_Attribute;
+
+ Atype : constant Node := Get_Type (Attr);
+ Str_Typ : constant Type_Acc := Get_Subtype_Object (Inst, Atype);
+ Name : constant Path_Instance_Name_Type :=
+ Get_Path_Instance_Name_Suffix (Attr);
+ Instance, Parent : Synth_Instance_Acc;
+ Rstr : Rstring;
+ Label : Node;
+ begin
+ if Name.Path_Instance = Null_Iir then
+ return String_To_Memtyp (Name.Suffix, Str_Typ);
+ end if;
+
+ Instance := Get_Instance_By_Scope
+ (Inst, Get_Info_Scope (Name.Path_Instance));
+
+ loop
+ Parent := Get_Instance_Parent (Instance);
+ if Parent = Root_Instance then
+ Parent := null;
+ end if;
+ Label := Get_Source_Scope (Instance);
+
+ case Get_Kind (Label) is
+ when Iir_Kind_Entity_Declaration =>
+ if Parent = null then
+ Prepend (Rstr, Image (Get_Identifier (Label)));
+ exit;
+ end if;
+ when Iir_Kind_Architecture_Body =>
+ if Is_Instance then
+ Prepend (Rstr, ')');
+ Prepend (Rstr, Image (Get_Identifier (Label)));
+ Prepend (Rstr, '(');
+ end if;
+
+ if Is_Instance or else Parent = null then
+ Prepend (Rstr, Image (Get_Identifier (Get_Entity (Label))));
+ end if;
+ if Parent = null then
+ Prepend (Rstr, ':');
+ exit;
+ end if;
+ when Iir_Kind_Block_Statement =>
+ Prepend (Rstr, Image (Get_Label (Label)));
+ Prepend (Rstr, ':');
+ when Iir_Kind_Iterator_Declaration =>
+ declare
+ Val : Valtyp;
+ begin
+ Val := Get_Value (Instance, Label);
+ Prepend (Rstr, ')');
+ Prepend (Rstr,
+ Synth_Image_Attribute_Str (Val, Get_Type (Label)));
+ Prepend (Rstr, '(');
+ end;
+ when Iir_Kind_Generate_Statement_Body =>
+ Prepend (Rstr, Image (Get_Label (Get_Parent (Label))));
+ Prepend (Rstr, ':');
+ when Iir_Kind_Component_Instantiation_Statement =>
+ if Is_Instance then
+ Prepend (Rstr, '@');
+ end if;
+ Prepend (Rstr, Image (Get_Label (Label)));
+ Prepend (Rstr, ':');
+ when others =>
+ Error_Kind ("Execute_Path_Instance_Name_Attribute",
+ Label);
+ end case;
+ Instance := Parent;
+ end loop;
+ declare
+ Str1 : String (1 .. Length (Rstr));
+ Len1 : Natural;
+ begin
+ Copy (Rstr, Str1, Len1);
+ Free (Rstr);
+ return String_To_Memtyp (Str1 & ':' & Name.Suffix, Str_Typ);
+ end;
+ end Exec_Path_Instance_Name_Attribute;
end Elab.Vhdl_Expr;