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.adb203
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 =>