diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/elab-vhdl_types.adb | 10 | ||||
-rw-r--r-- | src/synth/elab-vhdl_values.adb | 4 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.adb | 39 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.ads | 3 | ||||
-rw-r--r-- | src/synth/synth-vhdl_insts.adb | 5 | ||||
-rw-r--r-- | src/synth/synth-vhdl_oper.adb | 60 | ||||
-rw-r--r-- | src/synth/synth-vhdl_stmts.adb | 7 | ||||
-rw-r--r-- | src/vhdl/vhdl-annotations.adb | 23 |
8 files changed, 100 insertions, 51 deletions
diff --git a/src/synth/elab-vhdl_types.adb b/src/synth/elab-vhdl_types.adb index 7d726d154..54bd3469b 100644 --- a/src/synth/elab-vhdl_types.adb +++ b/src/synth/elab-vhdl_types.adb @@ -198,6 +198,8 @@ package body Elab.Vhdl_Types is function Synth_Record_Type_Definition (Syn_Inst : Synth_Instance_Acc; Def : Node) return Type_Acc is + Is_Subtype : constant Boolean := + Get_Kind (Def) = Iir_Kind_Record_Subtype_Definition; El_List : constant Node_Flist := Get_Elements_Declaration_List (Def); Rec_Els : Rec_El_Array_Acc; El : Node; @@ -210,7 +212,13 @@ package body Elab.Vhdl_Types is for I in Flist_First .. Flist_Last (El_List) loop El := Get_Nth_Element (El_List, I); El_Type := Get_Type (El); - El_Typ := Synth_Subtype_Indication_If_Anonymous (Syn_Inst, El_Type); + if Is_Subtype then + Synth_Subtype_Indication_If_Anonymous (Syn_Inst, El_Type); + El_Typ := Get_Subtype_Object (Syn_Inst, El_Type); + else + El_Typ := Synth_Subtype_Indication_If_Anonymous + (Syn_Inst, El_Type); + end if; Rec_Els.E (Iir_Index32 (I + 1)).Typ := El_Typ; end loop; diff --git a/src/synth/elab-vhdl_values.adb b/src/synth/elab-vhdl_values.adb index 90e72f223..017edc700 100644 --- a/src/synth/elab-vhdl_values.adb +++ b/src/synth/elab-vhdl_values.adb @@ -246,9 +246,9 @@ package body Elab.Vhdl_Values is Res.Val.Mem (I - 1) := Src.Val.Mem (I - 1); end loop; when Value_Net => - Res := (Src.Typ, Create_Value_Net (Src.Val.S)); + Res := (Src.Typ, Create_Value_Net (Src.Val.N)); when Value_Wire => - Res := (Src.Typ, Create_Value_Wire (Src.Val.S)); + Res := (Src.Typ, Create_Value_Wire (Src.Val.N)); when Value_File => Res := Create_Value_File (Src.Typ, Src.Val.File); when Value_Signal => diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb index ee691d8f5..c7eb117b6 100644 --- a/src/synth/synth-vhdl_expr.adb +++ b/src/synth/synth-vhdl_expr.adb @@ -893,6 +893,12 @@ package body Synth.Vhdl_Expr is end case; end Synth_Name; + procedure Bound_Error (Syn_Inst : Synth_Instance_Acc; Loc : Node) is + begin + Error_Msg_Synth (+Loc, "index not within bounds"); + Elab.Debugger.Debug_Error (Syn_Inst, Loc); + end Bound_Error; + -- Convert index IDX in PFX to an offset. -- SYN_INST and LOC are used in case of error. function Index_To_Offset @@ -902,8 +908,7 @@ package body Synth.Vhdl_Expr is Res : Value_Offsets; begin if not In_Bounds (Bnd, Int32 (Idx)) then - Error_Msg_Synth (+Loc, "index not within bounds"); - Elab.Debugger.Debug_Error (Syn_Inst, Loc); + Bound_Error (Syn_Inst, Loc); return (0, 0); end if; @@ -1000,13 +1005,15 @@ package body Synth.Vhdl_Expr is Name : Node; Pfx_Type : Type_Acc; Voff : out Net; - Off : out Value_Offsets) + Off : out Value_Offsets; + Error : out Boolean) is Ctxt : constant Context_Acc := Get_Build (Syn_Inst); Indexes : constant Iir_Flist := Get_Index_List (Name); El_Typ : constant Type_Acc := Get_Array_Element (Pfx_Type); Idx_Expr : Node; Idx_Val : Valtyp; + Idx : Int64; Bnd : Bound_Type; Stride : Uns32; Ivoff : Net; @@ -1014,6 +1021,7 @@ package body Synth.Vhdl_Expr is begin Voff := No_Net; Off := (0, 0); + Error := False; Stride := 1; for I in reverse Flist_First .. Flist_Last (Indexes) loop @@ -1022,9 +1030,8 @@ package body Synth.Vhdl_Expr is -- Use the base type as the subtype of the index is not synth-ed. Idx_Val := Synth_Expression_With_Basetype (Syn_Inst, Idx_Expr); if Idx_Val = No_Valtyp then - -- Propagate errorc - Voff := No_Net; - Off := (0, 0); + -- Propagate error. + Error := True; return; end if; @@ -1033,11 +1040,17 @@ package body Synth.Vhdl_Expr is Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (I + 1)); if Is_Static_Val (Idx_Val.Val) then - Idx_Off := Index_To_Offset (Syn_Inst, Bnd, - Get_Static_Discrete (Idx_Val), Name); - Off.Net_Off := Off.Net_Off + Idx_Off.Net_Off * Stride * El_Typ.W; - Off.Mem_Off := Off.Mem_Off - + Idx_Off.Mem_Off * Size_Type (Stride) * El_Typ.Sz; + Idx := Get_Static_Discrete (Idx_Val); + if not In_Bounds (Bnd, Int32 (Idx)) then + Bound_Error (Syn_Inst, Name); + Error := True; + else + Idx_Off := Index_To_Offset (Syn_Inst, Bnd, Idx, Name); + Off.Net_Off := Off.Net_Off + + Idx_Off.Net_Off * Stride * El_Typ.W; + Off.Mem_Off := Off.Mem_Off + + Idx_Off.Mem_Off * Size_Type (Stride) * El_Typ.Sz; + end if; else Ivoff := Dyn_Index_To_Offset (Ctxt, Bnd, Idx_Val, Name); Ivoff := Build_Memidx @@ -2202,6 +2215,10 @@ package body Synth.Vhdl_Expr is Dyn : Dyn_Name; begin Synth_Assignment_Prefix (Syn_Inst, Expr, Base, Typ, Off, Dyn); + if Base = No_Valtyp then + -- Propagate error. + return No_Valtyp; + end if; if Dyn.Voff = No_Net and then Is_Static (Base.Val) then Res := Create_Value_Memory (Typ); Copy_Memory diff --git a/src/synth/synth-vhdl_expr.ads b/src/synth/synth-vhdl_expr.ads index 7081aef95..33b908de3 100644 --- a/src/synth/synth-vhdl_expr.ads +++ b/src/synth/synth-vhdl_expr.ads @@ -119,7 +119,8 @@ package Synth.Vhdl_Expr is Name : Node; Pfx_Type : Type_Acc; Voff : out Net; - Off : out Value_Offsets); + Off : out Value_Offsets; + Error : out Boolean); -- Conversion to logic vector. type Digit_Index is new Natural; diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb index b02d2df69..cd6f55e2a 100644 --- a/src/synth/synth-vhdl_insts.adb +++ b/src/synth/synth-vhdl_insts.adb @@ -638,11 +638,12 @@ package body Synth.Vhdl_Insts is declare Voff : Net; Arr_Off : Value_Offsets; + Err : Boolean; begin Synth_Individual_Prefix (Syn_Inst, Inter_Inst, Get_Prefix (Formal), Off, Typ); - Synth_Indexed_Name (Syn_Inst, Formal, Typ, Voff, Arr_Off); - if Voff /= No_Net then + Synth_Indexed_Name (Syn_Inst, Formal, Typ, Voff, Arr_Off, Err); + if Voff /= No_Net or Err then raise Internal_Error; end if; Off := Off + Arr_Off.Net_Off; diff --git a/src/synth/synth-vhdl_oper.adb b/src/synth/synth-vhdl_oper.adb index e6221075d..b423bd149 100644 --- a/src/synth/synth-vhdl_oper.adb +++ b/src/synth/synth-vhdl_oper.adb @@ -1743,7 +1743,8 @@ package body Synth.Vhdl_Oper is return Create_Value_Net (Get_Net (Ctxt, Operand), Create_Res_Bound (Operand)); - when Iir_Predefined_Ieee_1164_Condition_Operator => + when Iir_Predefined_Ieee_1164_Condition_Operator + | Iir_Predefined_Bit_Condition => return Create_Value_Net (Get_Net (Ctxt, Operand), Get_Subtype_Object (Syn_Inst, Get_Type (Imp))); @@ -1846,6 +1847,21 @@ package body Synth.Vhdl_Oper is Res_Typ, False, Expr); end Synth_Find_Bit; + -- Resize ARG to SIZE bits according to IS_SIGNED. + function Synth_Resize (Ctxt : Context_Acc; + Arg : Valtyp; + Size : Width; + Is_Signed : Boolean; + Loc : Node) return Valtyp + is + N : Net; + begin + N := Get_Net (Ctxt, Arg); + N := Build2_Resize (Ctxt, N, Size, Is_Signed, Get_Location (Loc)); + return Create_Value_Net + (N, Create_Vec_Type_By_Length (Size, Logic_Type)); + end Synth_Resize; + function Synth_Dynamic_Predefined_Function_Call (Subprg_Inst : Synth_Instance_Acc; Expr : Node) return Valtyp is @@ -1865,7 +1881,6 @@ package body Synth.Vhdl_Oper is Arg : constant Valtyp := Get_Value (Subprg_Inst, Param1); Size_Vt : Valtyp; Size : Width; - Arg_Net : Net; begin Size_Vt := Get_Value (Subprg_Inst, Param2); Strip_Const (Size_Vt); @@ -1874,11 +1889,7 @@ package body Synth.Vhdl_Oper is return No_Valtyp; end if; Size := Uns32 (Read_Discrete (Size_Vt)); - Arg_Net := Get_Net (Ctxt, Arg); - Arg_Net := Build2_Resize (Ctxt, Arg_Net, Size, Is_Signed, - Get_Location (Expr)); - return Create_Value_Net - (Arg_Net, Create_Vec_Type_By_Length (Size, Logic_Type)); + return Synth_Resize (Ctxt, Arg, Size, Is_Signed, Expr); end Synth_Conv_Vector; L : Valtyp; @@ -1941,6 +1952,12 @@ package body Synth.Vhdl_Oper is when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Int => return Synth_Conv_Vector (False); + when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Uns_Uns => + declare + B : constant Bound_Type := Get_Array_Bound (R.Typ, 1); + begin + return Synth_Resize (Ctxt, L, B.Len, False, Expr); + end; when Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Nat_Sgn | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Int => return Synth_Conv_Vector (True); @@ -1992,30 +2009,17 @@ package body Synth.Vhdl_Oper is | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Sgn | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Sgn | Iir_Predefined_Ieee_Std_Logic_Arith_Sxt => - declare - W : Width; - begin - if not Is_Static (R.Val) then - Error_Msg_Synth (+Expr, "size must be constant"); - return No_Valtyp; - end if; - W := Uns32 (Read_Discrete (R)); - return Create_Value_Net - (Build2_Sresize (Ctxt, Get_Net (Ctxt, L), - W, Get_Location (Expr)), - Create_Vec_Type_By_Length (W, Logic_Type)); - end; + if not Is_Static (R.Val) then + Error_Msg_Synth (+Expr, "size must be constant"); + return No_Valtyp; + end if; + return Synth_Resize + (Ctxt, L, Uns32 (Read_Discrete (R)), True, Expr); when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Sgn => declare - B : Bound_Type; - W : Width; + B : constant Bound_Type := Get_Array_Bound (R.Typ, 1); begin - B := Get_Array_Bound (R.Typ, 1); - W := B.Len; - return Create_Value_Net - (Build2_Sresize (Ctxt, Get_Net (Ctxt, L), - W, Get_Location (Expr)), - Create_Vec_Type_By_Length (W, Logic_Type)); + return Synth_Resize (Ctxt, L, B.Len, True, Expr); end; when Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Uns_Nat | Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Sgn_Nat diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb index df8a851ce..3d8c7bba2 100644 --- a/src/synth/synth-vhdl_stmts.adb +++ b/src/synth/synth-vhdl_stmts.adb @@ -144,14 +144,17 @@ package body Synth.Vhdl_Stmts is declare Voff : Net; Off : Value_Offsets; + Err : Boolean; begin Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx), Dest_Base, Dest_Typ, Dest_Off, Dest_Dyn); Strip_Const (Dest_Base); - Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off); + Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off, Err); - if Voff = No_Net then + if Err then + Dest_Base := No_Valtyp; + elsif Voff = No_Net then -- Static index. Dest_Off := Dest_Off + Off; else diff --git a/src/vhdl/vhdl-annotations.adb b/src/vhdl/vhdl-annotations.adb index 630f3ef84..9fc9788bf 100644 --- a/src/vhdl/vhdl-annotations.adb +++ b/src/vhdl/vhdl-annotations.adb @@ -340,8 +340,8 @@ package body Vhdl.Annotations is then -- This subtype has created a new anonymous subtype for the -- element. - Annotate_Type_Definition - (Block_Info, Get_Element_Subtype (Def)); + El := Get_Element_Subtype (Def); + Annotate_Type_Definition (Block_Info, El); end if; if Flag_Synthesis then -- For the bounds. @@ -378,8 +378,23 @@ package body Vhdl.Annotations is when Iir_Kind_Record_Subtype_Definition => if Flag_Synthesis then - -- For the offsets. - Create_Object_Info (Block_Info, Def, Kind_Type); + declare + List : constant Iir_Flist := + Get_Elements_Declaration_List (Def); + El : Iir; + El_Type : Iir; + begin + for I in Flist_First .. Flist_Last (List) loop + El := Get_Nth_Element (List, I); + if Get_Subtype_Indication (El) /= Null_Iir then + El_Type := Get_Type (El); + Annotate_Anonymous_Type_Definition + (Block_Info, El_Type); + end if; + end loop; + -- For the offsets. + Create_Object_Info (Block_Info, Def, Kind_Type); + end; end if; when Iir_Kind_Access_Type_Definition => |