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.adb128
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;