diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-04-26 06:53:05 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-04-26 06:53:05 +0200 |
commit | e1d25901fe6fab3212377235964e1a7f0fe73010 (patch) | |
tree | 9802030068c9cce4a2ff5b5b4d07069341c34fed /src | |
parent | 791ff0c17bcaa8192ce25beda4392246fda9e8f7 (diff) | |
download | ghdl-e1d25901fe6fab3212377235964e1a7f0fe73010.tar.gz ghdl-e1d25901fe6fab3212377235964e1a7f0fe73010.tar.bz2 ghdl-e1d25901fe6fab3212377235964e1a7f0fe73010.zip |
synth-static_oper: do not depend on instance for static operations.
Preliminary work to support evaluation
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/elab-vhdl_objtypes.adb | 25 | ||||
-rw-r--r-- | src/synth/elab-vhdl_objtypes.ads | 14 | ||||
-rw-r--r-- | src/synth/elab-vhdl_types.adb | 39 | ||||
-rw-r--r-- | src/synth/elab-vhdl_types.ads | 3 | ||||
-rw-r--r-- | src/synth/synth-static_oper.adb | 30 | ||||
-rw-r--r-- | src/synth/synth-static_oper.ads | 8 | ||||
-rw-r--r-- | src/synth/synth-vhdl_oper.adb | 34 |
7 files changed, 91 insertions, 62 deletions
diff --git a/src/synth/elab-vhdl_objtypes.adb b/src/synth/elab-vhdl_objtypes.adb index 8e1d97324..4e2401fa0 100644 --- a/src/synth/elab-vhdl_objtypes.adb +++ b/src/synth/elab-vhdl_objtypes.adb @@ -363,8 +363,8 @@ package body Elab.Vhdl_Objtypes is Arr_El => El_Type))); end Create_Array_Type; - function Create_Unbounded_Array (Ndim : Dim_Type; El_Type : Type_Acc) - return Type_Acc + function Create_Unbounded_Array + (Ndim : Dim_Type; El_Type : Type_Acc; Idx1 : Type_Acc) return Type_Acc is subtype Unbounded_Type_Type is Type_Type (Type_Unbounded_Array); function Alloc is new Areapools.Alloc_On_Pool_Addr (Unbounded_Type_Type); @@ -375,10 +375,12 @@ package body Elab.Vhdl_Objtypes is Sz => 0, W => 0, Uarr_Ndim => Ndim, - Uarr_El => El_Type))); + Uarr_El => El_Type, + Uarr_Idx1 => Idx1))); end Create_Unbounded_Array; - function Create_Unbounded_Vector (El_Type : Type_Acc) return Type_Acc + function Create_Unbounded_Vector (El_Type : Type_Acc; Idx1 : Type_Acc) + return Type_Acc is subtype Unbounded_Type_Type is Type_Type (Type_Unbounded_Vector); function Alloc is new Areapools.Alloc_On_Pool_Addr (Unbounded_Type_Type); @@ -388,7 +390,8 @@ package body Elab.Vhdl_Objtypes is Al => El_Type.Al, Sz => 0, W => 0, - Uvec_El => El_Type))); + Uvec_El => El_Type, + Uvec_Idx1 => Idx1))); end Create_Unbounded_Vector; function Get_Array_Element (Arr_Type : Type_Acc) return Type_Acc is @@ -423,6 +426,18 @@ package body Elab.Vhdl_Objtypes is end case; end Get_Array_Bound; + function Get_Uarray_First_Index (Typ : Type_Acc) return Type_Acc is + begin + case Typ.Kind is + when Type_Unbounded_Vector => + return Typ.Uvec_Idx1; + when Type_Unbounded_Array => + return Typ.Uarr_Idx1; + when others => + raise Internal_Error; + end case; + end Get_Uarray_First_Index; + function Get_Range_Length (Rng : Discrete_Range_Type) return Uns32 is Len : Int64; diff --git a/src/synth/elab-vhdl_objtypes.ads b/src/synth/elab-vhdl_objtypes.ads index 59f18b534..0b0af6680 100644 --- a/src/synth/elab-vhdl_objtypes.ads +++ b/src/synth/elab-vhdl_objtypes.ads @@ -145,6 +145,7 @@ package Elab.Vhdl_Objtypes is Vec_El : Type_Acc; when Type_Unbounded_Vector => Uvec_El : Type_Acc; + Uvec_Idx1 : Type_Acc; when Type_Slice => Slice_El : Type_Acc; when Type_Array => @@ -153,6 +154,9 @@ package Elab.Vhdl_Objtypes is when Type_Unbounded_Array => Uarr_Ndim : Dim_Type; Uarr_El : Type_Acc; + -- Type of the first index. The only place we need the index is + -- for concatenation. + Uarr_Idx1 : Type_Acc; when Type_Record | Type_Unbounded_Record => Rec : Rec_El_Array_Acc; @@ -203,14 +207,15 @@ package Elab.Vhdl_Objtypes is return Type_Acc; function Create_Vector_Type (Bnd : Bound_Type; El_Type : Type_Acc) return Type_Acc; - function Create_Unbounded_Vector (El_Type : Type_Acc) return Type_Acc; + function Create_Unbounded_Vector (El_Type : Type_Acc; Idx1 : Type_Acc) + return Type_Acc; function Create_Slice_Type (Len : Uns32; El_Type : Type_Acc) return Type_Acc; function Create_Bound_Array (Ndims : Dim_Type) return Bound_Array_Acc; function Create_Array_Type (Bnd : Bound_Array_Acc; El_Type : Type_Acc) return Type_Acc; - function Create_Unbounded_Array (Ndim : Dim_Type; El_Type : Type_Acc) - return Type_Acc; + function Create_Unbounded_Array + (Ndim : Dim_Type; El_Type : Type_Acc; Idx1 : Type_Acc) return Type_Acc; function Create_Rec_El_Array (Nels : Iir_Index32) return Rec_El_Array_Acc; function Create_Record_Type (Els : Rec_El_Array_Acc) return Type_Acc; @@ -225,6 +230,9 @@ package Elab.Vhdl_Objtypes is function In_Bounds (Bnd : Bound_Type; V : Int32) return Boolean; function In_Range (Rng : Discrete_Range_Type; V : Int64) return Boolean; + -- Return the first index of an unbounded array or vector. + function Get_Uarray_First_Index (Typ : Type_Acc) return Type_Acc; + -- Return the bounds of dimension DIM of a vector/array. For a vector, -- DIM must be 1. function Get_Array_Bound (Typ : Type_Acc; Dim : Dim_Type) diff --git a/src/synth/elab-vhdl_types.adb b/src/synth/elab-vhdl_types.adb index 7e9106f95..e2cb469a1 100644 --- a/src/synth/elab-vhdl_types.adb +++ b/src/synth/elab-vhdl_types.adb @@ -158,6 +158,36 @@ package body Elab.Vhdl_Types is Len => Get_Range_Length (Rng)); end Synth_Bounds_From_Range; + function Create_Bounds_From_Length + (Bounds : Discrete_Range_Type; Len : Iir_Index32) return Bound_Type + is + Res : Bound_Type; + begin + Res := (Left => Int32 (Bounds.Left), + Right => 0, + Dir => Bounds.Dir, + Len => Uns32 (Len)); + + if Len = 0 then + -- Special case. + Res.Right := Res.Left; + case Bounds.Dir is + when Dir_To => + Res.Left := Res.Right + 1; + when Dir_Downto => + Res.Left := Res.Right - 1; + end case; + else + case Bounds.Dir is + when Dir_To => + Res.Right := Res.Left + Int32 (Len - 1); + when Dir_Downto => + Res.Right := Res.Left - Int32 (Len - 1); + end case; + end if; + return Res; + end Create_Bounds_From_Length; + procedure Synth_Subtype_Indication_If_Anonymous (Syn_Inst : Synth_Instance_Acc; Atype : Node) is begin @@ -181,16 +211,21 @@ package body Elab.Vhdl_Types is is El_Type : constant Node := Get_Element_Subtype (Def); Ndims : constant Natural := Get_Nbr_Dimensions (Def); + Idx : Node; El_Typ : Type_Acc; + Idx_Typ : Type_Acc; Typ : Type_Acc; begin Synth_Subtype_Indication_If_Anonymous (Syn_Inst, El_Type); El_Typ := Get_Subtype_Object (Syn_Inst, El_Type); + Idx := Get_Index_Type (Def, 0); + Idx_Typ := Get_Subtype_Object (Syn_Inst, Idx); + if El_Typ.Kind in Type_Nets and then Ndims = 1 then - Typ := Create_Unbounded_Vector (El_Typ); + Typ := Create_Unbounded_Vector (El_Typ, Idx_Typ); else - Typ := Create_Unbounded_Array (Dim_Type (Ndims), El_Typ); + Typ := Create_Unbounded_Array (Dim_Type (Ndims), El_Typ, Idx_Typ); end if; return Typ; end Synth_Array_Type_Definition; diff --git a/src/synth/elab-vhdl_types.ads b/src/synth/elab-vhdl_types.ads index 30ee6e0ae..941ba80d6 100644 --- a/src/synth/elab-vhdl_types.ads +++ b/src/synth/elab-vhdl_types.ads @@ -44,6 +44,9 @@ package Elab.Vhdl_Types is function Synth_Bounds_From_Range (Syn_Inst : Synth_Instance_Acc; Atype : Node) return Bound_Type; + function Create_Bounds_From_Length + (Bounds : Discrete_Range_Type; Len : Iir_Index32) return Bound_Type; + function Synth_Array_Subtype_Indication (Syn_Inst : Synth_Instance_Acc; Atype : Node) return Type_Acc; diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index a5356398e..0a1545da8 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -21,20 +21,19 @@ with Types_Utils; use Types_Utils; with Grt.Types; use Grt.Types; -with Vhdl.Utils; use Vhdl.Utils; with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164; with Elab.Vhdl_Values; use Elab.Vhdl_Values; with Elab.Memtype; use Elab.Memtype; with Elab.Vhdl_Files; with Elab.Vhdl_Expr; use Elab.Vhdl_Expr; +with Elab.Vhdl_Types; with Netlists; use Netlists; with Synth.Errors; use Synth.Errors; with Synth.Source; use Synth.Source; with Synth.Vhdl_Expr; use Synth.Vhdl_Expr; -with Synth.Vhdl_Oper; with Synth.Ieee.Std_Logic_1164; use Synth.Ieee.Std_Logic_1164; with Synth.Ieee.Numeric_Std; use Synth.Ieee.Numeric_Std; @@ -105,16 +104,14 @@ package body Synth.Static_Oper is end case; end Check_Integer_Overflow; - function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc; - Imp : Node; + function Synth_Static_Dyadic_Predefined (Imp : Node; + Res_Typ : Type_Acc; Left : Memtyp; Right : Memtyp; Expr : Node) return Memtyp is Def : constant Iir_Predefined_Functions := Get_Implicit_Definition (Imp); - Res_Typ : constant Type_Acc := - Get_Subtype_Object (Syn_Inst, Get_Type (Expr)); begin case Def is when Iir_Predefined_Error => @@ -305,9 +302,8 @@ package body Synth.Static_Oper is Res : Memtyp; begin Check_Matching_Bounds (Le_Typ, Re_Typ, Expr); - Bnd := Synth.Vhdl_Oper.Create_Bounds_From_Length - (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), - L_Len + R_Len); + Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length + (Get_Uarray_First_Index (Res_Typ).Drange, L_Len + R_Len); Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd, Le_Typ); Res := Create_Memory (Res_St); @@ -329,8 +325,8 @@ package body Synth.Static_Oper is Res : Memtyp; begin Check_Matching_Bounds (Left.Typ, Re_Typ, Expr); - Bnd := Synth.Vhdl_Oper.Create_Bounds_From_Length - (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), 1 + Rlen); + Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length + (Get_Uarray_First_Index (Res_Typ).Drange, 1 + Rlen); Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd, Re_Typ); Res := Create_Memory (Res_St); @@ -348,8 +344,8 @@ package body Synth.Static_Oper is Res : Memtyp; begin Check_Matching_Bounds (Le_Typ, Right.Typ, Expr); - Bnd := Synth.Vhdl_Oper.Create_Bounds_From_Length - (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), Llen + 1); + Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length + (Get_Uarray_First_Index (Res_Typ).Drange, Llen + 1); Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd, Le_Typ); Res := Create_Memory (Res_St); @@ -674,17 +670,13 @@ package body Synth.Static_Oper is return Create_Memory_U8 (Std_Ulogic'Pos (Res), El_Typ); end Synth_Vector_Reduce; - function Synth_Static_Monadic_Predefined (Syn_Inst : Synth_Instance_Acc; - Imp : Node; + function Synth_Static_Monadic_Predefined (Imp : Node; Operand : Memtyp; + Oper_Typ : Type_Acc; Expr : Node) return Memtyp is Def : constant Iir_Predefined_Functions := Get_Implicit_Definition (Imp); - Inter_Chain : constant Node := - Get_Interface_Declaration_Chain (Imp); - Oper_Type : constant Node := Get_Type (Inter_Chain); - Oper_Typ : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Oper_Type); begin case Def is when Iir_Predefined_Boolean_Not diff --git a/src/synth/synth-static_oper.ads b/src/synth/synth-static_oper.ads index 797b73de6..bb27b1e79 100644 --- a/src/synth/synth-static_oper.ads +++ b/src/synth/synth-static_oper.ads @@ -22,14 +22,14 @@ with Elab.Vhdl_Objtypes; use Elab.Vhdl_Objtypes; with Vhdl.Nodes; use Vhdl.Nodes; package Synth.Static_Oper is - function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc; - Imp : Node; + function Synth_Static_Dyadic_Predefined (Imp : Node; + Res_Typ : Type_Acc; Left : Memtyp; Right : Memtyp; Expr : Node) return Memtyp; - function Synth_Static_Monadic_Predefined (Syn_Inst : Synth_Instance_Acc; - Imp : Node; + function Synth_Static_Monadic_Predefined (Imp : Node; Operand : Memtyp; + Oper_Typ : Type_Acc; Expr : Node) return Memtyp; function Synth_Static_Predefined_Function_Call diff --git a/src/synth/synth-vhdl_oper.adb b/src/synth/synth-vhdl_oper.adb index a3a4a46c2..7f995cbb2 100644 --- a/src/synth/synth-vhdl_oper.adb +++ b/src/synth/synth-vhdl_oper.adb @@ -166,34 +166,10 @@ package body Synth.Vhdl_Oper is (Syn_Inst : Synth_Instance_Acc; Atype : Iir; Len : Iir_Index32) return Bound_Type is - Res : Bound_Type; Index_Bounds : Discrete_Range_Type; begin Synth_Discrete_Range (Syn_Inst, Atype, Index_Bounds); - - Res := (Left => Int32 (Index_Bounds.Left), - Right => 0, - Dir => Index_Bounds.Dir, - Len => Uns32 (Len)); - - if Len = 0 then - -- Special case. - Res.Right := Res.Left; - case Index_Bounds.Dir is - when Dir_To => - Res.Left := Res.Right + 1; - when Dir_Downto => - Res.Left := Res.Right - 1; - end case; - else - case Index_Bounds.Dir is - when Dir_To => - Res.Right := Res.Left + Int32 (Len - 1); - when Dir_Downto => - Res.Right := Res.Left - Int32 (Len - 1); - end case; - end if; - return Res; + return Create_Bounds_From_Length (Index_Bounds, Len); end Create_Bounds_From_Length; -- Do a match comparison between CST and OPER. @@ -772,7 +748,7 @@ package body Synth.Vhdl_Oper is if Is_Static_Val (Left.Val) and Is_Static_Val (Right.Val) then Srec := Synth_Static_Dyadic_Predefined - (Syn_Inst, Imp, + (Imp, Expr_Typ, Get_Value_Memtyp (Left), Get_Value_Memtyp (Right), Expr); if Srec = Null_Memtyp then return No_Valtyp; @@ -1706,9 +1682,9 @@ package body Synth.Vhdl_Oper is Strip_Const (Operand); if Is_Static_Val (Operand.Val) then - return Create_Value_Memtyp (Synth_Static_Monadic_Predefined - (Syn_Inst, Imp, - Get_Value_Memtyp (Operand), Loc)); + return Create_Value_Memtyp + (Synth_Static_Monadic_Predefined + (Imp, Get_Value_Memtyp (Operand), Oper_Typ, Loc)); end if; case Def is |