diff options
Diffstat (limited to 'src/synth/elab-vhdl_expr.adb')
-rw-r--r-- | src/synth/elab-vhdl_expr.adb | 203 |
1 files changed, 80 insertions, 123 deletions
diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb index a920d2a8f..3693f3249 100644 --- a/src/synth/elab-vhdl_expr.adb +++ b/src/synth/elab-vhdl_expr.adb @@ -25,7 +25,6 @@ with Errorout; use Errorout; with Vhdl.Errors; use Vhdl.Errors; with Vhdl.Utils; use Vhdl.Utils; with Vhdl.Evaluation; use Vhdl.Evaluation; -with Vhdl.Annotations; use Vhdl.Annotations; with Elab.Memtype; use Elab.Memtype; with Elab.Vhdl_Heap; use Elab.Vhdl_Heap; @@ -37,42 +36,12 @@ with Synth.Vhdl_Stmts; use Synth.Vhdl_Stmts; with Synth.Vhdl_Oper; use Synth.Vhdl_Oper; with Synth.Vhdl_Aggr; with Synth.Vhdl_Expr; use Synth.Vhdl_Expr; +with Synth.Vhdl_Eval; use Synth.Vhdl_Eval; with Grt.Types; with Grt.To_Strings; package body Elab.Vhdl_Expr is - function Synth_Array_Bounds (Syn_Inst : Synth_Instance_Acc; - Atype : Node; - Dim : Dim_Type) return Bound_Type - is - Info : constant Sim_Info_Acc := Get_Info (Atype); - begin - if Info = null then - pragma Assert (Get_Type_Declarator (Atype) = Null_Node); - declare - Index_Type : constant Node := - Get_Index_Type (Atype, Natural (Dim - 1)); - begin - return Synth_Bounds_From_Range (Syn_Inst, Index_Type); - end; - else - declare - Bnds : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Atype); - begin - case Bnds.Kind is - when Type_Vector => - pragma Assert (Dim = 1); - return Bnds.Vbound; - when Type_Array => - return Bnds.Abounds.D (Dim); - when others => - raise Internal_Error; - end case; - end; - end if; - end Synth_Array_Bounds; - function Synth_Bounds_From_Length (Atype : Node; Len : Int32) return Bound_Type is @@ -94,8 +63,8 @@ package body Elab.Vhdl_Expr is end case; end Synth_Bounds_From_Length; - function Synth_Simple_Aggregate (Syn_Inst : Synth_Instance_Acc; - Aggr : Node) return Valtyp + function Exec_Simple_Aggregate (Syn_Inst : Synth_Instance_Acc; + Aggr : Node) return Valtyp is Aggr_Type : constant Node := Get_Type (Aggr); pragma Assert (Get_Nbr_Dimensions (Aggr_Type) = 1); @@ -104,7 +73,6 @@ package body Elab.Vhdl_Expr is Els : constant Iir_Flist := Get_Simple_Aggregate_List (Aggr); Last : constant Natural := Flist_Last (Els); Bnd : Bound_Type; - Bnds : Bound_Array_Acc; Res_Type : Type_Acc; Val : Valtyp; Res : Valtyp; @@ -116,9 +84,7 @@ package body Elab.Vhdl_Expr is if El_Typ.Kind in Type_Nets then Res_Type := Create_Vector_Type (Bnd, El_Typ); else - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bnd; - Res_Type := Create_Array_Type (Bnds, El_Typ); + Res_Type := Create_Array_Type (Bnd, True, El_Typ); end if; Res := Create_Value_Memory (Res_Type); @@ -132,7 +98,7 @@ package body Elab.Vhdl_Expr is end loop; return Res; - end Synth_Simple_Aggregate; + end Exec_Simple_Aggregate; -- Change the bounds of VAL. function Reshape_Value (Val : Valtyp; Ntype : Type_Acc) return Valtyp is @@ -221,18 +187,28 @@ package body Elab.Vhdl_Expr is when Type_Array => pragma Assert (Vtype.Kind = Type_Array); -- Check bounds. - for I in Vtype.Abounds.D'Range loop - if Vtype.Abounds.D (I).Len /= Dtype.Abounds.D (I).Len then - Error_Msg_Elab (+Loc, "mismatching array bounds"); - return No_Valtyp; + declare + Src_Typ, Dst_Typ : Type_Acc; + begin + Src_Typ := Vtype; + Dst_Typ := Dtype; + loop + pragma Assert (Src_Typ.Alast = Dst_Typ.Alast); + if Src_Typ.Abound.Len /= Dst_Typ.Abound.Len then + Error_Msg_Elab (+Loc, "mismatching array bounds"); + return No_Valtyp; + end if; + exit when Src_Typ.Alast; + Src_Typ := Src_Typ.Arr_El; + Dst_Typ := Dst_Typ.Arr_El; + end loop; + -- TODO: check element. + if Bounds then + return Reshape_Value (Vt, Dtype); + else + return Vt; end if; - end loop; - -- TODO: check element. - if Bounds then - return Reshape_Value (Vt, Dtype); - else - return Vt; - end if; + end; when Type_Unbounded_Array => pragma Assert (Vtype.Kind = Type_Array); return Vt; @@ -258,8 +234,8 @@ package body Elab.Vhdl_Expr is end case; end Exec_Subtype_Conversion; - function Synth_Value_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node) - return Valtyp + function Exec_Value_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node) + return Valtyp is Param : constant Node := Get_Parameter (Attr); Etype : constant Node := Get_Type (Attr); @@ -297,7 +273,7 @@ package body Elab.Vhdl_Expr is end case; return Create_Value_Discrete (Val, Dtype); end; - end Synth_Value_Attribute; + end Exec_Value_Attribute; function Synth_Image_Attribute_Str (Val : Valtyp; Expr_Type : Iir) return String @@ -348,37 +324,18 @@ package body Elab.Vhdl_Expr is return Str (First .. Str'Last) & ' ' & Name_Table.Image (Id); end; when others => - Error_Kind ("execute_image_attribute", Expr_Type); + Error_Kind ("synth_image_attribute_str", Expr_Type); end case; end Synth_Image_Attribute_Str; - function String_To_Valtyp (Str : String; Styp : Type_Acc) return Valtyp - is - Len : constant Natural := Str'Length; - Bnd : Bound_Array_Acc; - Typ : Type_Acc; - Res : Valtyp; - begin - Bnd := Create_Bound_Array (1); - Bnd.D (1) := (Dir => Dir_To, Left => 1, Right => Int32 (Len), - Len => Uns32 (Len)); - Typ := Create_Array_Type (Bnd, Styp.Uarr_El); - - Res := Create_Value_Memory (Typ); - for I in Str'Range loop - Write_U8 (Res.Val.Mem + Size_Type (I - Str'First), - Character'Pos (Str (I))); - end loop; - return Res; - end String_To_Valtyp; - - function Synth_Image_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node) - return Valtyp + function Exec_Image_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node) + return Valtyp is Param : constant Node := Get_Parameter (Attr); Etype : constant Node := Get_Type (Attr); V : Valtyp; Dtype : Type_Acc; + Res : Memtyp; begin -- The parameter is expected to be static. V := Exec_Expression (Syn_Inst, Param); @@ -392,21 +349,24 @@ package body Elab.Vhdl_Expr is end if; Strip_Const (V); - return String_To_Valtyp + Res := String_To_Memtyp (Synth_Image_Attribute_Str (V, Get_Type (Param)), Dtype); - end Synth_Image_Attribute; + return Create_Value_Memtyp (Res); + end Exec_Image_Attribute; - function Synth_Instance_Name_Attribute + function Exec_Instance_Name_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node) return Valtyp is Atype : constant Node := Get_Type (Attr); Atyp : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Atype); Name : constant Path_Instance_Name_Type := Get_Path_Instance_Name_Suffix (Attr); + Res : Memtyp; begin -- Return a truncated name, as the prefix is not completly known. - return String_To_Valtyp (Name.Suffix, Atyp); - end Synth_Instance_Name_Attribute; + Res := String_To_Memtyp (Name.Suffix, Atyp); + return Create_Value_Memtyp (Res); + end Exec_Instance_Name_Attribute; -- Convert index IDX in PFX to an offset. -- SYN_INST and LOC are used in case of error. @@ -448,12 +408,11 @@ package body Elab.Vhdl_Expr is (Typ : Type_Acc; Bnd : out Bound_Type; El_Typ : out Type_Acc) is begin case Typ.Kind is - when Type_Vector => - El_Typ := Typ.Vec_El; - Bnd := Typ.Vbound; - when Type_Array => + when Type_Array + | Type_Vector => + pragma Assert (Typ.Alast); El_Typ := Typ.Arr_El; - Bnd := Typ.Abounds.D (1); + Bnd := Typ.Abound; when others => raise Internal_Error; end case; @@ -463,27 +422,22 @@ package body Elab.Vhdl_Expr is (Btyp : Type_Acc; Bnd : Bound_Type; El_Typ : Type_Acc) return Type_Acc is Res : Type_Acc; - Bnds : Bound_Array_Acc; begin case Btyp.Kind is when Type_Vector => pragma Assert (El_Typ.Kind in Type_Nets); - Res := Create_Vector_Type (Bnd, Btyp.Vec_El); + Res := Create_Vector_Type (Bnd, Btyp.Arr_El); when Type_Unbounded_Vector => pragma Assert (El_Typ.Kind in Type_Nets); - Res := Create_Vector_Type (Bnd, Btyp.Uvec_El); + Res := Create_Vector_Type (Bnd, Btyp.Uarr_El); when Type_Array => - pragma Assert (Btyp.Abounds.Ndim = 1); + pragma Assert (Btyp.Alast); pragma Assert (Is_Bounded_Type (Btyp.Arr_El)); - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bnd; - Res := Create_Array_Type (Bnds, Btyp.Arr_El); + Res := Create_Array_Type (Bnd, True, Btyp.Arr_El); when Type_Unbounded_Array => - pragma Assert (Btyp.Uarr_Ndim = 1); + pragma Assert (Btyp.Ulast); pragma Assert (Is_Bounded_Type (El_Typ)); - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bnd; - Res := Create_Array_Type (Bnds, El_Typ); + Res := Create_Array_Type (Bnd, True, El_Typ); when others => raise Internal_Error; end case; @@ -519,7 +473,7 @@ package body Elab.Vhdl_Expr is Strip_Const (Idx_Val); - Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (I + 1)); + Bnd := Get_Array_Bound (Pfx_Type); pragma Assert (Is_Static (Idx_Val.Val)); @@ -744,6 +698,13 @@ package body Elab.Vhdl_Expr is Val := Elab.Vhdl_Heap.Synth_Dereference (Read_Access (Val)); return Val.Typ; end; + when Iir_Kind_Function_Call => + declare + Val : Valtyp; + begin + Val := Synth.Vhdl_Expr.Synth_Expression (Syn_Inst, Name); + return Val.Typ; + end; when others => Error_Kind ("exec_name_subtype", Name); end case; @@ -803,10 +764,7 @@ package body Elab.Vhdl_Expr is begin Exec_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), Dest_Base, Dest_Typ, Dest_Off); - Dest_Off.Net_Off := - Dest_Off.Net_Off + Dest_Typ.Rec.E (Idx + 1).Boff; - Dest_Off.Mem_Off := - Dest_Off.Mem_Off + Dest_Typ.Rec.E (Idx + 1).Moff; + Dest_Off := Dest_Off + Dest_Typ.Rec.E (Idx + 1).Offs; Dest_Typ := Dest_Typ.Rec.E (Idx + 1).Typ; end; @@ -901,7 +859,7 @@ package body Elab.Vhdl_Expr is return Synth_Subtype_Indication (Syn_Inst, Get_Type (Expr)); when others => - Vhdl.Errors.Error_Kind ("synth_type_of_object", Expr); + Vhdl.Errors.Error_Kind ("exec_type_of_object", Expr); end case; return null; end Exec_Type_Of_Object; @@ -943,7 +901,9 @@ package body Elab.Vhdl_Expr is | Iir_Kind_Array_Subtype_Definition => case Conv_Typ.Kind is when Type_Vector - | Type_Unbounded_Vector => + | Type_Unbounded_Vector + | Type_Array + | Type_Unbounded_Array => return Val; when others => Error_Msg_Elab @@ -994,9 +954,9 @@ package body Elab.Vhdl_Expr is return False; end Error_Ieee_Operator; - function Synth_String_Literal - (Syn_Inst : Synth_Instance_Acc; Str : Node; Str_Typ : Type_Acc) - return Valtyp + function Exec_String_Literal (Syn_Inst : Synth_Instance_Acc; + Str : Node; + Str_Typ : Type_Acc) return Valtyp is pragma Unreferenced (Syn_Inst); pragma Assert (Get_Kind (Str) = Iir_Kind_String_Literal8); @@ -1005,16 +965,14 @@ package body Elab.Vhdl_Expr is Str_Type : constant Node := Get_Type (Str); El_Type : Type_Acc; Bounds : Bound_Type; - Bnds : Bound_Array_Acc; Res_Type : Type_Acc; Res : Valtyp; Pos : Nat8; begin case Str_Typ.Kind is - when Type_Vector => - Bounds := Str_Typ.Vbound; - when Type_Array => - Bounds := Str_Typ.Abounds.D (1); + when Type_Vector + | Type_Array => + Bounds := Str_Typ.Abound; when Type_Unbounded_Vector | Type_Unbounded_Array => Bounds := Synth_Bounds_From_Length @@ -1027,9 +985,7 @@ package body Elab.Vhdl_Expr is if El_Type.Kind in Type_Nets then Res_Type := Create_Vector_Type (Bounds, El_Type); else - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bounds; - Res_Type := Create_Array_Type (Bnds, El_Type); + Res_Type := Create_Array_Type (Bounds, True, El_Type); end if; Res := Create_Value_Memory (Res_Type); @@ -1044,7 +1000,7 @@ package body Elab.Vhdl_Expr is end loop; return Res; - end Synth_String_Literal; + end Exec_String_Literal; -- Return the left bound if the direction of the range is LEFT_DIR. function Synth_Low_High_Type_Attribute @@ -1224,7 +1180,8 @@ package body Elab.Vhdl_Expr is pragma Assert (Is_Static (Val.Val)); Res := Create_Value_Memory (Res_Typ); Copy_Memory - (Res.Val.Mem, Val.Val.Mem + Val.Typ.Rec.E (Idx + 1).Moff, + (Res.Val.Mem, + Val.Val.Mem + Val.Typ.Rec.E (Idx + 1).Offs.Mem_Off, Res_Typ.Sz); return Res; end; @@ -1246,7 +1203,7 @@ package body Elab.Vhdl_Expr is return Create_Value_Discrete (Get_Physical_Value (Expr), Expr_Type); when Iir_Kind_String_Literal8 => - return Synth_String_Literal (Syn_Inst, Expr, Expr_Type); + return Exec_String_Literal (Syn_Inst, Expr, Expr_Type); when Iir_Kind_Enumeration_Literal => return Exec_Name (Syn_Inst, Expr); when Iir_Kind_Type_Conversion => @@ -1260,7 +1217,7 @@ package body Elab.Vhdl_Expr is Imp : constant Node := Get_Implementation (Expr); begin case Get_Implicit_Definition (Imp) is - when Iir_Predefined_Pure_Functions + when Iir_Predefined_Operators | Iir_Predefined_Ieee_Numeric_Std_Binary_Operators => return Synth_Operator_Function_Call (Syn_Inst, Expr); when Iir_Predefined_None => @@ -1272,7 +1229,7 @@ package body Elab.Vhdl_Expr is when Iir_Kind_Aggregate => return Synth.Vhdl_Aggr.Synth_Aggregate (Syn_Inst, Expr, Expr_Type); when Iir_Kind_Simple_Aggregate => - return Synth_Simple_Aggregate (Syn_Inst, Expr); + return Exec_Simple_Aggregate (Syn_Inst, Expr); when Iir_Kind_Parenthesis_Expression => return Exec_Expression_With_Type (Syn_Inst, Get_Expression (Expr), Expr_Type); @@ -1358,11 +1315,11 @@ package body Elab.Vhdl_Expr is when Iir_Kind_High_Type_Attribute => return Synth_Low_High_Type_Attribute (Syn_Inst, Expr, Dir_Downto); when Iir_Kind_Value_Attribute => - return Synth_Value_Attribute (Syn_Inst, Expr); + return Exec_Value_Attribute (Syn_Inst, Expr); when Iir_Kind_Image_Attribute => - return Synth_Image_Attribute (Syn_Inst, Expr); + return Exec_Image_Attribute (Syn_Inst, Expr); when Iir_Kind_Instance_Name_Attribute => - return Synth_Instance_Name_Attribute (Syn_Inst, Expr); + return Exec_Instance_Name_Attribute (Syn_Inst, Expr); when Iir_Kind_Null_Literal => return Create_Value_Access (Null_Heap_Index, Expr_Type); when Iir_Kind_Allocator_By_Subtype => |