diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-03-08 08:05:29 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-03-08 08:05:29 +0100 |
commit | c3af2b181bb1b68bfcf6190e03485189765161bc (patch) | |
tree | e4fa3f7099c48c0610c9b0badd510df385a7d410 /src/synth | |
parent | 311e9448678c6c8ecf1af3dcd7f98c5cd1437c77 (diff) | |
download | ghdl-c3af2b181bb1b68bfcf6190e03485189765161bc.tar.gz ghdl-c3af2b181bb1b68bfcf6190e03485189765161bc.tar.bz2 ghdl-c3af2b181bb1b68bfcf6190e03485189765161bc.zip |
synth: handle concatenation of unbounded types. Fix #1993
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/elab-vhdl_errors.ads | 1 | ||||
-rw-r--r-- | src/synth/elab-vhdl_expr.adb | 51 | ||||
-rw-r--r-- | src/synth/elab-vhdl_expr.ads | 12 | ||||
-rw-r--r-- | src/synth/synth-static_oper.adb | 17 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.adb | 44 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.ads | 9 | ||||
-rw-r--r-- | src/synth/synth-vhdl_insts.adb | 4 | ||||
-rw-r--r-- | src/synth/synth-vhdl_oper.adb | 33 | ||||
-rw-r--r-- | src/synth/synth-vhdl_stmts.adb | 4 |
9 files changed, 64 insertions, 111 deletions
diff --git a/src/synth/elab-vhdl_errors.ads b/src/synth/elab-vhdl_errors.ads index d4cd19a24..4d9d2788e 100644 --- a/src/synth/elab-vhdl_errors.ads +++ b/src/synth/elab-vhdl_errors.ads @@ -26,6 +26,7 @@ package Elab.Vhdl_Errors is procedure Error_Msg_Elab (Loc : Location_Type; Msg : String; Args : Earg_Arr := No_Eargs); + -- procedure Warning_Msg_Synth (Loc : Location_Type; -- Msg : String; -- Arg1 : Earg_Type); diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb index 0933e772e..d105fc730 100644 --- a/src/synth/elab-vhdl_expr.adb +++ b/src/synth/elab-vhdl_expr.adb @@ -16,6 +16,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <gnu.org/licenses>. +with Types; use Types; with Name_Table; with Std_Names; with Str_Table; @@ -35,42 +36,12 @@ with Elab.Debugger; 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 Grt.Types; with Grt.To_Strings; package body Elab.Vhdl_Expr is - function Get_Value_Memtyp (V : Valtyp) return Memtyp is - begin - case V.Val.Kind is - when Value_Memory => - return (V.Typ, V.Val.Mem); - when Value_Const => - return Get_Memtyp (V); - when Value_Alias => - declare - Res : Memtyp; - begin - Res := Get_Value_Memtyp ((V.Val.A_Typ, V.Val.A_Obj)); - return (V.Typ, Res.Mem + V.Val.A_Off.Mem_Off); - end; - when others => - raise Internal_Error; - end case; - end Get_Value_Memtyp; - - function Get_Static_Discrete (V : Valtyp) return Int64 is - begin - case V.Val.Kind is - when Value_Memory => - return Read_Discrete (V); - when Value_Const => - return Read_Discrete (Get_Memtyp (V)); - when others => - raise Internal_Error; - end case; - end Get_Static_Discrete; - function Synth_Array_Bounds (Syn_Inst : Synth_Instance_Acc; Atype : Node; Dim : Dim_Type) return Bound_Type @@ -464,6 +435,11 @@ package body Elab.Vhdl_Expr is return Res; end Index_To_Offset; + procedure Check_Matching_Bounds (L, R : Type_Acc; Loc : Node) is + begin + null; + end Check_Matching_Bounds; + -- Return the bounds of a one dimensional array/vector type and the -- width of the element. procedure Get_Onedimensional_Array_Bounds @@ -482,26 +458,30 @@ package body Elab.Vhdl_Expr is end Get_Onedimensional_Array_Bounds; function Create_Onedimensional_Array_Subtype - (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc + (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); when Type_Unbounded_Vector => + pragma Assert (El_Typ.Kind in Type_Nets); Res := Create_Vector_Type (Bnd, Btyp.Uvec_El); when Type_Array => pragma Assert (Btyp.Abounds.Ndim = 1); + 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); when Type_Unbounded_Array => pragma Assert (Btyp.Uarr_Ndim = 1); + pragma Assert (Is_Bounded_Type (El_Typ)); Bnds := Create_Bound_Array (1); Bnds.D (1) := Bnd; - Res := Create_Array_Type (Bnds, Btyp.Uarr_El); + Res := Create_Array_Type (Bnds, El_Typ); when others => raise Internal_Error; end case; @@ -846,7 +826,7 @@ package body Elab.Vhdl_Expr is -- Fixed slice. Dest_Typ := Create_Onedimensional_Array_Subtype - (Dest_Typ, Res_Bnd); + (Dest_Typ, Res_Bnd, El_Typ); Dest_Off.Net_Off := Dest_Off.Net_Off + Sl_Off.Net_Off; Dest_Off.Mem_Off := Dest_Off.Mem_Off + Sl_Off.Mem_Off; end; @@ -881,7 +861,8 @@ package body Elab.Vhdl_Expr is Get_Onedimensional_Array_Bounds (Pfx_Typ, Pfx_Bnd, El_Typ); Exec_Slice_Suffix (Syn_Inst, Expr, Pfx_Bnd, El_Typ, Res_Bnd, Sl_Off); - return Create_Onedimensional_Array_Subtype (Pfx_Typ, Res_Bnd); + return Create_Onedimensional_Array_Subtype + (Pfx_Typ, Res_Bnd, El_Typ); end; when Iir_Kind_Indexed_Name => declare diff --git a/src/synth/elab-vhdl_expr.ads b/src/synth/elab-vhdl_expr.ads index 77231b1a4..723f5bf91 100644 --- a/src/synth/elab-vhdl_expr.ads +++ b/src/synth/elab-vhdl_expr.ads @@ -16,8 +16,6 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <gnu.org/licenses>. -with Types; use Types; - with Vhdl.Nodes; use Vhdl.Nodes; with Elab.Vhdl_Context; use Elab.Vhdl_Context; @@ -25,12 +23,6 @@ with Elab.Vhdl_Objtypes; use Elab.Vhdl_Objtypes; with Elab.Vhdl_Values; use Elab.Vhdl_Values; package Elab.Vhdl_Expr is - -- For a static value V, return the value. - function Get_Static_Discrete (V : Valtyp) return Int64; - - -- Return the memory (as a memtyp) of static value V. - function Get_Value_Memtyp (V : Valtyp) return Memtyp; - -- Return the bounds of a one dimensional array/vector type and the -- width of the element. procedure Get_Onedimensional_Array_Bounds @@ -38,7 +30,9 @@ package Elab.Vhdl_Expr is -- Create an array subtype from bound BND. function Create_Onedimensional_Array_Subtype - (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc; + (Btyp : Type_Acc; Bnd : Bound_Type; El_Typ : Type_Acc) return Type_Acc; + + procedure Check_Matching_Bounds (L, R : Type_Acc; Loc : Node); -- Return the type of EXPR without evaluating it. function Exec_Type_Of_Object (Syn_Inst : Synth_Instance_Acc; Expr : Node) diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index cc52cd0f4..8b431b21c 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -27,6 +27,7 @@ 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 Netlists; use Netlists; @@ -297,14 +298,18 @@ package body Synth.Static_Oper is Iir_Index32 (Get_Bound_Length (Left.Typ, 1)); R_Len : constant Iir_Index32 := Iir_Index32 (Get_Bound_Length (Right.Typ, 1)); + Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ); + Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ); Bnd : Bound_Type; Res_St : Type_Acc; 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); - Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd); + Res_St := Create_Onedimensional_Array_Subtype + (Res_Typ, Bnd, Le_Typ); Res := Create_Memory (Res_St); if Left.Typ.Sz > 0 then Copy_Memory (Res.Mem, Left.Mem, Left.Typ.Sz); @@ -318,13 +323,16 @@ package body Synth.Static_Oper is declare Rlen : constant Iir_Index32 := Get_Array_Flat_Length (Right.Typ); + Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ); Bnd : Bound_Type; Res_St : Type_Acc; Res : Memtyp; begin + Check_Matching_Bounds (Left.Typ, Right.Typ, Expr); Bnd := Synth.Vhdl_Oper.Create_Bounds_From_Length (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), 1 + Rlen); - Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd); + Res_St := Create_Onedimensional_Array_Subtype + (Res_Typ, Bnd, Re_Typ); Res := Create_Memory (Res_St); Copy_Memory (Res.Mem, Left.Mem, Left.Typ.Sz); Copy_Memory (Res.Mem + Left.Typ.Sz, @@ -334,13 +342,16 @@ package body Synth.Static_Oper is when Iir_Predefined_Array_Element_Concat => declare Llen : constant Iir_Index32 := Get_Array_Flat_Length (Left.Typ); + Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ); Bnd : Bound_Type; Res_St : Type_Acc; 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); - Res_St := Create_Onedimensional_Array_Subtype (Res_Typ, Bnd); + Res_St := Create_Onedimensional_Array_Subtype + (Res_Typ, Bnd, Le_Typ); Res := Create_Memory (Res_St); Copy_Memory (Res.Mem, Left.Mem, Left.Typ.Sz); Copy_Memory (Res.Mem + Left.Typ.Sz, diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb index c7eb117b6..83143a082 100644 --- a/src/synth/synth-vhdl_expr.adb +++ b/src/synth/synth-vhdl_expr.adb @@ -957,50 +957,6 @@ package body Synth.Vhdl_Expr is return Off; end Dyn_Index_To_Offset; - -- Return the bounds of a one dimensional array/vector type and the - -- width of the element. - procedure Get_Onedimensional_Array_Bounds - (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 => - El_Typ := Typ.Arr_El; - Bnd := Typ.Abounds.D (1); - when others => - raise Internal_Error; - end case; - end Get_Onedimensional_Array_Bounds; - - function Create_Onedimensional_Array_Subtype - (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc - is - Res : Type_Acc; - Bnds : Bound_Array_Acc; - begin - case Btyp.Kind is - when Type_Vector => - Res := Create_Vector_Type (Bnd, Btyp.Vec_El); - when Type_Unbounded_Vector => - Res := Create_Vector_Type (Bnd, Btyp.Uvec_El); - when Type_Array => - pragma Assert (Btyp.Abounds.Ndim = 1); - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bnd; - Res := Create_Array_Type (Bnds, Btyp.Arr_El); - when Type_Unbounded_Array => - pragma Assert (Btyp.Uarr_Ndim = 1); - Bnds := Create_Bound_Array (1); - Bnds.D (1) := Bnd; - Res := Create_Array_Type (Bnds, Btyp.Uarr_El); - when others => - raise Internal_Error; - end case; - return Res; - end Create_Onedimensional_Array_Subtype; - procedure Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc; Name : Node; Pfx_Type : Type_Acc; diff --git a/src/synth/synth-vhdl_expr.ads b/src/synth/synth-vhdl_expr.ads index 33b908de3..5591234bb 100644 --- a/src/synth/synth-vhdl_expr.ads +++ b/src/synth/synth-vhdl_expr.ads @@ -58,15 +58,6 @@ package Synth.Vhdl_Expr is -- False means either not positive or unknown. function Is_Positive (V : Valtyp) return Boolean; - -- Return the bounds of a one dimensional array/vector type and the - -- width of the element. - procedure Get_Onedimensional_Array_Bounds - (Typ : Type_Acc; Bnd : out Bound_Type; El_Typ : out Type_Acc); - - -- Create an array subtype from bound BND. - function Create_Onedimensional_Array_Subtype - (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc; - procedure From_Std_Logic (Enum : Int64; Val : out Uns32; Zx : out Uns32); procedure From_Bit (Enum : Int64; Val : out Uns32); procedure To_Logic diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb index cd6f55e2a..ff3685978 100644 --- a/src/synth/synth-vhdl_insts.adb +++ b/src/synth/synth-vhdl_insts.adb @@ -46,6 +46,7 @@ with Elab.Memtype; use Elab.Memtype; with Elab.Vhdl_Files; with Elab.Debugger; with Elab.Vhdl_Errors; +with Elab.Vhdl_Expr; use Elab.Vhdl_Expr; with Synth.Vhdl_Environment; use Synth.Vhdl_Environment.Env; with Synth.Vhdl_Stmts; use Synth.Vhdl_Stmts; @@ -667,7 +668,8 @@ package body Synth.Vhdl_Insts is raise Internal_Error; end if; Off := Off + Sl_Off.Net_Off; - Typ := Create_Onedimensional_Array_Subtype (Typ, Res_Bnd); + Typ := Create_Onedimensional_Array_Subtype + (Typ, Res_Bnd, El_Typ); end; when others => Vhdl.Errors.Error_Kind ("synth_individual_prefix", Formal); diff --git a/src/synth/synth-vhdl_oper.adb b/src/synth/synth-vhdl_oper.adb index cc6c978b8..a3a4a46c2 100644 --- a/src/synth/synth-vhdl_oper.adb +++ b/src/synth/synth-vhdl_oper.adb @@ -34,6 +34,7 @@ with Netlists.Utils; with Elab.Memtype; use Elab.Memtype; with Elab.Vhdl_Types; use Elab.Vhdl_Types; +with Elab.Vhdl_Expr; use Elab.Vhdl_Expr; with Synth.Errors; use Synth.Errors; with Synth.Vhdl_Stmts; use Synth.Vhdl_Stmts; @@ -986,9 +987,12 @@ package body Synth.Vhdl_Oper is when Iir_Predefined_Array_Element_Concat => declare L : constant Net := Get_Net (Ctxt, Left); + Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ); Bnd : Bound_Type; + Res_Typ : Type_Acc; N : Net; begin + Check_Matching_Bounds (Le_Typ, Right.Typ, Expr); N := Build2_Concat2 (Ctxt, L, Get_Net (Ctxt, Right)); Set_Location (N, Expr); Bnd := Create_Bounds_From_Length @@ -996,15 +1000,19 @@ package body Synth.Vhdl_Oper is Get_Index_Type (Get_Type (Expr), 0), Iir_Index32 (Get_Bound_Length (Left.Typ, 1) + 1)); - return Create_Value_Net - (N, Create_Onedimensional_Array_Subtype (Left_Typ, Bnd)); + Res_Typ := Create_Onedimensional_Array_Subtype + (Left_Typ, Bnd, Le_Typ); + return Create_Value_Net (N, Res_Typ); end; when Iir_Predefined_Element_Array_Concat => declare R : constant Net := Get_Net (Ctxt, Right); + Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ); Bnd : Bound_Type; + Res_Typ : Type_Acc; N : Net; begin + Check_Matching_Bounds (Left.Typ, Re_Typ, Expr); N := Build2_Concat2 (Ctxt, Get_Net (Ctxt, Left), R); Set_Location (N, Expr); Bnd := Create_Bounds_From_Length @@ -1012,29 +1020,37 @@ package body Synth.Vhdl_Oper is Get_Index_Type (Get_Type (Expr), 0), Iir_Index32 (Get_Bound_Length (Right.Typ, 1) + 1)); - return Create_Value_Net - (N, Create_Onedimensional_Array_Subtype (Right_Typ, Bnd)); + Res_Typ := Create_Onedimensional_Array_Subtype + (Right_Typ, Bnd, Re_Typ); + return Create_Value_Net (N, Res_Typ); end; when Iir_Predefined_Element_Element_Concat => declare N : Net; Bnd : Bound_Type; + Res_Typ : Type_Acc; begin + Check_Matching_Bounds (Left.Typ, Right.Typ, Expr); N := Build2_Concat2 (Ctxt, Get_Net (Ctxt, Left), Get_Net (Ctxt, Right)); Set_Location (N, Expr); Bnd := Create_Bounds_From_Length (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), 2); - return Create_Value_Net - (N, Create_Onedimensional_Array_Subtype (Expr_Typ, Bnd)); + Res_Typ := Create_Onedimensional_Array_Subtype + (Expr_Typ, Bnd, Left.Typ); + return Create_Value_Net (N, Res_Typ); end; when Iir_Predefined_Array_Array_Concat => declare + Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ); + Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ); L : constant Net := Get_Net (Ctxt, Left); R : constant Net := Get_Net (Ctxt, Right); Bnd : Bound_Type; + Res_Typ : Type_Acc; N : Net; begin + Check_Matching_Bounds (Le_Typ, Re_Typ, Expr); N := Build2_Concat2 (Ctxt, L, R); Set_Location (N, Expr); Bnd := Create_Bounds_From_Length @@ -1043,8 +1059,9 @@ package body Synth.Vhdl_Oper is Iir_Index32 (Get_Bound_Length (Left.Typ, 1) + Get_Bound_Length (Right.Typ, 1))); - return Create_Value_Net - (N, Create_Onedimensional_Array_Subtype (Expr_Typ, Bnd)); + Res_Typ := Create_Onedimensional_Array_Subtype + (Expr_Typ, Bnd, Le_Typ); + return Create_Value_Net (N, Res_Typ); end; when Iir_Predefined_Integer_Plus => return Synth_Int_Dyadic (Id_Add); diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb index 3d8c7bba2..b28c6f0f5 100644 --- a/src/synth/synth-vhdl_stmts.adb +++ b/src/synth/synth-vhdl_stmts.adb @@ -44,7 +44,7 @@ with PSL.NFAs; with Elab.Memtype; use Elab.Memtype; with Elab.Vhdl_Heap; with Elab.Vhdl_Types; use Elab.Vhdl_Types; -with Elab.Vhdl_Expr; +with Elab.Vhdl_Expr; use Elab.Vhdl_Expr; with Elab.Debugger; with Synth.Errors; use Synth.Errors; @@ -219,7 +219,7 @@ package body Synth.Vhdl_Stmts is if Sl_Voff = No_Net then -- Fixed slice. Dest_Typ := Create_Onedimensional_Array_Subtype - (Dest_Typ, Res_Bnd); + (Dest_Typ, Res_Bnd, El_Typ); Dest_Off.Net_Off := Dest_Off.Net_Off + Sl_Off.Net_Off; Dest_Off.Mem_Off := Dest_Off.Mem_Off + Sl_Off.Mem_Off; else |