diff options
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/synth-oper.adb | 46 | ||||
-rw-r--r-- | src/synth/synth-static_oper.adb | 88 | ||||
-rw-r--r-- | src/synth/synth-static_oper.ads | 4 |
3 files changed, 106 insertions, 32 deletions
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb index 57b4a294a..dd02da330 100644 --- a/src/synth/synth-oper.adb +++ b/src/synth/synth-oper.adb @@ -791,6 +791,11 @@ package body Synth.Oper is Operand := Synth_Subtype_Conversion (Operand, Oper_Typ, False, Loc); Strip_Const (Operand); + if Is_Static_Val (Operand) then + return Synth_Static_Monadic_Predefined + (Syn_Inst, Imp, Operand, Loc); + end if; + case Def is when Iir_Predefined_Error => return null; @@ -798,11 +803,7 @@ package body Synth.Oper is return Synth_Bit_Monadic (Id_Not); when Iir_Predefined_Boolean_Not | Iir_Predefined_Bit_Not => - if Is_Static (Operand) then - return Create_Value_Discrete (1 - Operand.Scal, Oper_Typ); - else - return Synth_Bit_Monadic (Id_Not); - end if; + return Synth_Bit_Monadic (Id_Not); when Iir_Predefined_Ieee_1164_Vector_Not | Iir_Predefined_Ieee_Numeric_Std_Not_Uns | Iir_Predefined_Ieee_Numeric_Std_Not_Sgn => @@ -815,34 +816,15 @@ package body Synth.Oper is when Iir_Predefined_Ieee_1164_Vector_Or_Reduce => return Synth_Vec_Reduce_Monadic(Id_Red_Or); when Iir_Predefined_Ieee_1164_Condition_Operator => - if Operand.Typ.Kind = Type_Logic - and then Operand.Kind = Value_Discrete - then - -- Constant std_logic: need to convert. - declare - Val : Uns32; - Zx : Uns32; - begin - From_Std_Logic (Operand.Scal, Val, Zx); - return Create_Value_Discrete - (Boolean'Pos (Val = 1 and Zx = 0), Boolean_Type); - end; - else - return Operand; - end if; + return Operand; when Iir_Predefined_Integer_Negation => - if Is_Static (Operand) then - return Create_Value_Discrete (-Operand.Scal, Operand.Typ); - else - declare - N : Net; - begin - N := Build_Monadic - (Build_Context, Id_Neg, Get_Net (Operand)); - Set_Location (N, Loc); - return Create_Value_Net (N, Operand.Typ); - end; - end if; + declare + N : Net; + begin + N := Build_Monadic (Build_Context, Id_Neg, Get_Net (Operand)); + Set_Location (N, Loc); + return Create_Value_Net (N, Operand.Typ); + end; when others => Error_Msg_Synth (+Loc, diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index 3fc12174b..f6d00191e 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -341,4 +341,92 @@ package body Synth.Static_Oper is raise Internal_Error; end case; end Synth_Static_Dyadic_Predefined; + + function Synth_Vector_Monadic + (Vec : Value_Acc; Op : Table_1d) return Value_Acc + is + El_Typ : constant Type_Acc := Vec.Typ.Vec_El; + Arr : Value_Array_Acc; + begin + Arr := Create_Value_Array (Vec.Arr.Len); + for I in Arr.V'Range loop + declare + V : constant Std_Ulogic := Std_Ulogic'Val (Vec.Arr.V (I).Scal); + begin + Arr.V (I) := + Create_Value_Discrete (Std_Ulogic'Pos (Op (V)), El_Typ); + end; + end loop; + + return Create_Value_Const_Array (Create_Res_Bound (Vec.Typ), Arr); + end Synth_Vector_Monadic; + + function Synth_Vector_Reduce + (Init : Std_Ulogic; Vec : Value_Acc; Op : Table_2d) return Value_Acc + is + El_Typ : constant Type_Acc := Vec.Typ.Vec_El; + Res : Std_Ulogic; + begin + Res := Init; + for I in Vec.Arr.V'Range loop + declare + V : constant Std_Ulogic := + Std_Ulogic'Val (Vec.Arr.V (I).Scal); + begin + Res := Op (Res, V); + end; + end loop; + + return Create_Value_Discrete (Std_Ulogic'Pos (Res), El_Typ); + end Synth_Vector_Reduce; + + function Synth_Static_Monadic_Predefined (Syn_Inst : Synth_Instance_Acc; + Imp : Node; + Operand : Value_Acc; + Expr : Node) return Value_Acc + 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_Value_Type (Syn_Inst, Oper_Type); + -- Res_Typ : constant Type_Acc := + -- Get_Value_Type (Syn_Inst, Get_Type (Expr)); + begin + case Def is + when Iir_Predefined_Boolean_Not + | Iir_Predefined_Bit_Not => + return Create_Value_Discrete (1 - Operand.Scal, Oper_Typ); + + when Iir_Predefined_Integer_Negation => + return Create_Value_Discrete (-Operand.Scal, Oper_Typ); + + when Iir_Predefined_Floating_Negation => + return Create_Value_Float (-Operand.Fp, Oper_Typ); + + when Iir_Predefined_Ieee_1164_Condition_Operator => + -- Constant std_logic: need to convert. + declare + Val : Uns32; + Zx : Uns32; + begin + From_Std_Logic (Operand.Scal, Val, Zx); + return Create_Value_Discrete + (Boolean'Pos (Val = 1 and Zx = 0), Boolean_Type); + end; + + when Iir_Predefined_Ieee_1164_Vector_Not => + return Synth_Vector_Monadic (Operand, Not_Table); + + when Iir_Predefined_Ieee_1164_Vector_Or_Reduce => + return Synth_Vector_Reduce ('0', Operand, Or_Table); + + when others => + Error_Msg_Synth + (+Expr, "synth_static_monadic_predefined: unhandled " + & Iir_Predefined_Functions'Image (Def)); + raise Internal_Error; + end case; + end Synth_Static_Monadic_Predefined; end Synth.Static_Oper; diff --git a/src/synth/synth-static_oper.ads b/src/synth/synth-static_oper.ads index 1cf5d9e68..d166a8469 100644 --- a/src/synth/synth-static_oper.ads +++ b/src/synth/synth-static_oper.ads @@ -28,4 +28,8 @@ package Synth.Static_Oper is Left : Value_Acc; Right : Value_Acc; Expr : Node) return Value_Acc; + function Synth_Static_Monadic_Predefined (Syn_Inst : Synth_Instance_Acc; + Imp : Node; + Operand : Value_Acc; + Expr : Node) return Value_Acc; end Synth.Static_Oper; |