diff options
Diffstat (limited to 'src/synth/elab-vhdl_expr.adb')
-rw-r--r-- | src/synth/elab-vhdl_expr.adb | 128 |
1 files changed, 125 insertions, 3 deletions
diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb index ee15c7e52..d9ad9f27d 100644 --- a/src/synth/elab-vhdl_expr.adb +++ b/src/synth/elab-vhdl_expr.adb @@ -23,6 +23,7 @@ with Str_Table; with Netlists; with Vhdl.Errors; use Vhdl.Errors; +with Vhdl.Scanner; with Vhdl.Utils; use Vhdl.Utils; with Vhdl.Evaluation; use Vhdl.Evaluation; @@ -36,7 +37,9 @@ with Synth.Vhdl_Eval; use Synth.Vhdl_Eval; with Synth.Errors; use Synth.Errors; with Grt.Types; +with Grt.Vhdl_Types; with Grt.To_Strings; +with Grt.Vstrings; package body Elab.Vhdl_Expr is function Synth_Bounds_From_Length (Atype : Node; Len : Int32) @@ -124,17 +127,48 @@ package body Elab.Vhdl_Expr is end if; declare - Str : constant String := Value_To_String (V); + Value : constant String := Value_To_String (V); + First, Last : Integer; Res_N : Node; Val : Int64; begin + -- LRM93 14.1 Predefined attributes. + -- Leading and trailing whitespace are ignored. + First := Value'First; + Last := Value'Last; + while First <= Last loop + exit when not Vhdl.Scanner.Is_Whitespace (Value (First)); + First := First + 1; + end loop; + while Last >= First loop + exit when not Vhdl.Scanner.Is_Whitespace (Value (Last)); + Last := Last - 1; + end loop; + case Get_Kind (Btype) is when Iir_Kind_Enumeration_Type_Definition => - Res_N := Eval_Value_Attribute (Str, Etype, Attr); + Res_N := Eval_Value_Attribute + (Value (First .. Last), Etype, Attr); Val := Int64 (Get_Enum_Pos (Res_N)); Free_Iir (Res_N); when Iir_Kind_Integer_Type_Definition => - Val := Int64'Value (Str); + declare + use Grt.To_Strings; + use Grt.Types; + use Grt.Vhdl_Types; + Value1 : String renames Value (First .. Last); + Res : Value_I64_Result; + begin + Res := Value_I64 (To_Std_String_Basep (Value1'Address), + Value1'Length, 0); + if Res.Status = Value_Ok then + Val := Int64 (Res.Val); + else + Error_Msg_Synth + (Syn_Inst, Attr, "incorrect 'value string"); + return No_Valtyp; + end if; + end; when others => Error_Msg_Elab (+Attr, "unhandled type for 'value"); return No_Valtyp; @@ -420,4 +454,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; |