diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-03-21 17:16:08 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-03-21 17:16:08 +0100 |
commit | 134c6ed91339538eeb0c62b25de4c2ea79e89e37 (patch) | |
tree | 9b3da160a0b299533ee8a5c0c7553ff29be0469b /src/synth | |
parent | e63bc8249ddfca1176b72f038ba8b9fa12b0f38c (diff) | |
download | ghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.tar.gz ghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.tar.bz2 ghdl-134c6ed91339538eeb0c62b25de4c2ea79e89e37.zip |
synth: handle numeric_std minimum/maximum. Fix #1168
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/ghdlsynth_gates.h | 92 | ||||
-rw-r--r-- | src/synth/netlists-builders.adb | 9 | ||||
-rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 12 | ||||
-rw-r--r-- | src/synth/netlists-gates.ads | 92 | ||||
-rw-r--r-- | src/synth/synth-oper.adb | 352 |
5 files changed, 296 insertions, 261 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h index 1611a81e1..adc1e87b9 100644 --- a/src/synth/ghdlsynth_gates.h +++ b/src/synth/ghdlsynth_gates.h @@ -14,50 +14,54 @@ enum Module_Id { Id_Xnor = 8, Id_Add = 9, Id_Sub = 10, - Id_Umul = 11, - Id_Smul = 12, - Id_Udiv = 13, - Id_Sdiv = 14, - Id_Umod = 15, - Id_Smod = 16, - Id_Srem = 17, - Id_Not = 18, - Id_Neg = 19, - Id_Abs = 20, - Id_Lsl = 22, - Id_Lsr = 23, - Id_Asr = 24, - Id_Rol = 25, - Id_Ror = 26, - Id_Eq = 27, - Id_Ne = 28, - Id_Ule = 29, - Id_Sle = 30, - Id_Ult = 31, - Id_Slt = 32, - Id_Uge = 33, - Id_Sge = 34, - Id_Ugt = 35, - Id_Sgt = 36, - Id_Red_And = 37, - Id_Red_Or = 38, - Id_Concat2 = 40, - Id_Concat3 = 41, - Id_Concat4 = 42, - Id_Concatn = 43, - Id_Mux2 = 44, - Id_Mux4 = 45, - Id_Signal = 46, - Id_Isignal = 47, - Id_Output = 48, - Id_Ioutput = 49, - Id_Port = 50, - Id_Dff = 52, - Id_Adff = 53, - Id_Idff = 54, - Id_Iadff = 55, - Id_Mdff = 56, - Id_Midff = 57, + Id_Umin = 11, + Id_Smin = 12, + Id_Umax = 13, + Id_Smax = 14, + Id_Umul = 15, + Id_Smul = 16, + Id_Udiv = 17, + Id_Sdiv = 18, + Id_Umod = 19, + Id_Smod = 20, + Id_Srem = 21, + Id_Not = 22, + Id_Neg = 23, + Id_Abs = 24, + Id_Lsl = 25, + Id_Lsr = 26, + Id_Asr = 27, + Id_Rol = 28, + Id_Ror = 29, + Id_Eq = 30, + Id_Ne = 31, + Id_Ule = 32, + Id_Sle = 33, + Id_Ult = 34, + Id_Slt = 35, + Id_Uge = 36, + Id_Sge = 37, + Id_Ugt = 38, + Id_Sgt = 39, + Id_Red_And = 40, + Id_Red_Or = 41, + Id_Concat2 = 42, + Id_Concat3 = 43, + Id_Concat4 = 44, + Id_Concatn = 45, + Id_Mux2 = 46, + Id_Mux4 = 47, + Id_Signal = 48, + Id_Isignal = 49, + Id_Output = 50, + Id_Ioutput = 51, + Id_Port = 52, + Id_Dff = 56, + Id_Adff = 57, + Id_Idff = 58, + Id_Iadff = 59, + Id_Mdff = 60, + Id_Midff = 61, Id_Utrunc = 64, Id_Strunc = 65, Id_Uextend = 66, diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index 0e7f16815..6262295de 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -592,6 +592,15 @@ package body Netlists.Builders is Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Sub), Get_Identifier ("sub"), Id_Sub); + Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umin), + Get_Identifier ("umin"), Id_Umin); + Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smin), + Get_Identifier ("smin"), Id_Smin); + Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umax), + Get_Identifier ("umax"), Id_Umax); + Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smax), + Get_Identifier ("smax"), Id_Smax); + Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Umul), Get_Identifier ("umul"), Id_Umul); Create_Dyadic_Module (Design, Res.M_Dyadic (Id_Smul), diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb index 22dc86e84..423a9ed96 100644 --- a/src/synth/netlists-disp_vhdl.adb +++ b/src/synth/netlists-disp_vhdl.adb @@ -943,6 +943,18 @@ package body Netlists.Disp_Vhdl is Disp_Template (" \o0 <= std_logic_vector (\ui0 - \ui1);" & NL, Inst); end if; + when Id_Umin => + Disp_Template (" \o0 <= \i0 when \ui0 < \ui1 else \i1;" & NL, + Inst); + when Id_Smin => + Disp_Template (" \o0 <= \i0 when \si0 < \si1 else \i1;" & NL, + Inst); + when Id_Umax => + Disp_Template (" \o0 <= \i0 when \ui0 > \ui1 else \i1;" & NL, + Inst); + when Id_Smax => + Disp_Template (" \o0 <= \i0 when \si0 > \si1 else \i1;" & NL, + Inst); when Id_Umul => Disp_Template (" \o0 <= std_logic_vector (resize (\ui0 * \ui1, \n0));" & NL, diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index c6c1c4815..b60420c22 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -33,72 +33,76 @@ package Netlists.Gates is Id_Add : constant Module_Id := 9; Id_Sub : constant Module_Id := 10; - Id_Umul : constant Module_Id := 11; - Id_Smul : constant Module_Id := 12; - Id_Udiv : constant Module_Id := 13; - Id_Sdiv : constant Module_Id := 14; - Id_Umod : constant Module_Id := 15; - Id_Smod : constant Module_Id := 16; - Id_Srem : constant Module_Id := 17; + Id_Umin : constant Module_Id := 11; + Id_Smin : constant Module_Id := 12; + Id_Umax : constant Module_Id := 13; + Id_Smax : constant Module_Id := 14; + Id_Umul : constant Module_Id := 15; + Id_Smul : constant Module_Id := 16; + Id_Udiv : constant Module_Id := 17; + Id_Sdiv : constant Module_Id := 18; + Id_Umod : constant Module_Id := 19; + Id_Smod : constant Module_Id := 20; + Id_Srem : constant Module_Id := 21; subtype Dyadic_Module_Id is Module_Id range Id_And .. Id_Srem; - Id_Not : constant Module_Id := 18; - Id_Neg : constant Module_Id := 19; - Id_Abs : constant Module_Id := 20; + Id_Not : constant Module_Id := 22; + Id_Neg : constant Module_Id := 23; + Id_Abs : constant Module_Id := 24; subtype Monadic_Module_Id is Module_Id range Id_Not .. Id_Abs; -- Logical and arithmetic shifts. -- FIXME: clarify right operand: width, large values - Id_Lsl : constant Module_Id := 22; - Id_Lsr : constant Module_Id := 23; - Id_Asr : constant Module_Id := 24; + Id_Lsl : constant Module_Id := 25; + Id_Lsr : constant Module_Id := 26; + Id_Asr : constant Module_Id := 27; subtype Shift_Module_Id is Module_Id range Id_Lsl .. Id_Asr; -- Rotations. -- FIXME: clarify right operand. - Id_Rol : constant Module_Id := 25; - Id_Ror : constant Module_Id := 26; + Id_Rol : constant Module_Id := 28; + Id_Ror : constant Module_Id := 29; subtype Rotate_Module_Id is Module_Id range Id_Lsl .. Id_Asr; subtype Shift_Rotate_Module_Id is Module_Id range Id_Lsl .. Id_Ror; - Id_Eq : constant Module_Id := 27; - Id_Ne : constant Module_Id := 28; - Id_Ule : constant Module_Id := 29; - Id_Sle : constant Module_Id := 30; - Id_Ult : constant Module_Id := 31; - Id_Slt : constant Module_Id := 32; - Id_Uge : constant Module_Id := 33; - Id_Sge : constant Module_Id := 34; - Id_Ugt : constant Module_Id := 35; - Id_Sgt : constant Module_Id := 36; + Id_Eq : constant Module_Id := 30; + Id_Ne : constant Module_Id := 31; + Id_Ule : constant Module_Id := 32; + Id_Sle : constant Module_Id := 33; + Id_Ult : constant Module_Id := 34; + Id_Slt : constant Module_Id := 35; + Id_Uge : constant Module_Id := 36; + Id_Sge : constant Module_Id := 37; + Id_Ugt : constant Module_Id := 38; + Id_Sgt : constant Module_Id := 39; subtype Compare_Module_Id is Module_Id range Id_Eq .. Id_Sgt; - Id_Red_And : constant Module_Id := 37; - Id_Red_Or : constant Module_Id := 38; + Id_Red_And : constant Module_Id := 40; + Id_Red_Or : constant Module_Id := 41; subtype Reduce_Module_Id is Module_Id range Id_Red_And .. Id_Red_Or; - Id_Concat2 : constant Module_Id := 40; - Id_Concat3 : constant Module_Id := 41; - Id_Concat4 : constant Module_Id := 42; + Id_Concat2 : constant Module_Id := 42; + Id_Concat3 : constant Module_Id := 43; + Id_Concat4 : constant Module_Id := 44; subtype Concat_Module_Id is Module_Id range Id_Concat2 .. Id_Concat4; -- Concatenation with N inputs. - Id_Concatn : constant Module_Id := 43; + Id_Concatn : constant Module_Id := 45; -- Inputs: s, i0, i1 -- Output: o - Id_Mux2 : constant Module_Id := 44; + Id_Mux2 : constant Module_Id := 46; -- Inputs: s, i0, i1, s2, s3 -- Output: o - Id_Mux4 : constant Module_Id := 45; + Id_Mux4 : constant Module_Id := 47; subtype Mux_Module_Id is Module_Id range Id_Mux2 .. Id_Mux4; @@ -110,11 +114,11 @@ package Netlists.Gates is -- by a gate (and thus the value of the output could be read), but that -- driving value may not be available early enough. -- Id_Ioutput is an output with an initial value. - Id_Signal : constant Module_Id := 46; - Id_Isignal : constant Module_Id := 47; - Id_Output : constant Module_Id := 48; - Id_Ioutput : constant Module_Id := 49; - Id_Port : constant Module_Id := 50; + Id_Signal : constant Module_Id := 48; + Id_Isignal : constant Module_Id := 49; + Id_Output : constant Module_Id := 50; + Id_Ioutput : constant Module_Id := 51; + Id_Port : constant Module_Id := 52; -- Note: initial values must be constant nets. -- @@ -124,7 +128,7 @@ package Netlists.Gates is -- Inputs: 0: CLK -- 1: D -- Output: 0: Q - Id_Dff : constant Module_Id := 52; + Id_Dff : constant Module_Id := 56; -- A DFF with an asynchronous reset. Note that the asynchronous reset -- has priority over the clock. When RST is asserted, the value is @@ -134,7 +138,7 @@ package Netlists.Gates is -- 2: RST -- 3: RST_VAL -- Output: 0: Q - Id_Adff : constant Module_Id := 53; + Id_Adff : constant Module_Id := 57; -- A simple DFF with an initial value (must be constant). This is -- for FPGAs. @@ -142,7 +146,7 @@ package Netlists.Gates is -- 1: D -- 2: INIT (initial value) -- Output: 0: Q - Id_Idff : constant Module_Id := 54; + Id_Idff : constant Module_Id := 58; -- A DFF with an asynchronous reset and an initial value. -- Inputs: 0: CLK @@ -151,14 +155,14 @@ package Netlists.Gates is -- 3: RST_VAL -- 4: INIT (initial value) -- Output: 0: Q - Id_Iadff : constant Module_Id := 55; + Id_Iadff : constant Module_Id := 59; -- Multi clock dff. ELSE is the output of the next DFF. -- Inputs: 0: CLK -- 1: D -- 2: ELSE -- Output: 0: Q - Id_Mdff : constant Module_Id := 56; + Id_Mdff : constant Module_Id := 60; -- Multi clock dff with initial value. ELSE is the output of the next DFF. -- Inputs: 0: CLK @@ -166,7 +170,7 @@ package Netlists.Gates is -- 2: ELSE -- 3: Init -- Output: 0: Q - Id_Midff : constant Module_Id := 57; + Id_Midff : constant Module_Id := 61; -- Width change: truncate or extend. Sign is know in order to possibly -- detect loss of value. diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb index e3fd0c714..8efaca0c3 100644 --- a/src/synth/synth-oper.adb +++ b/src/synth/synth-oper.adb @@ -245,6 +245,114 @@ package body Synth.Oper is return Res; end Synth_Match; + -- Note: LEFT or RIGHT can be a single bit. + function Synth_Dyadic_Uns_Uns + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W); + El_Typ : Type_Acc; + Rtype : Type_Acc; + L1, R1 : Net; + N : Net; + begin + if Left.Typ.Kind = Type_Vector then + El_Typ := Left.Typ.Vec_El; + elsif Right.Typ.Kind = Type_Vector then + El_Typ := Right.Typ.Vec_El; + else + raise Internal_Error; + end if; + Rtype := Create_Vec_Type_By_Length (W, El_Typ); + L1 := Synth_Uresize (Left, W, Expr); + R1 := Synth_Uresize (Right, W, Expr); + N := Build_Dyadic (Build_Context, Id, L1, R1); + Set_Location (N, Expr); + return Create_Value_Net (N, Rtype); + end Synth_Dyadic_Uns_Uns; + + function Synth_Dyadic_Uns_Nat + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + L : constant Net := Get_Net (Left); + R1 : Net; + N : Net; + begin + R1 := Synth_Uresize (Right, Left.Typ.W, Expr); + N := Build_Dyadic (Build_Context, Id, L, R1); + Set_Location (N, Expr); + return Create_Value_Net (N, Create_Res_Bound (Left)); + end Synth_Dyadic_Uns_Nat; + + function Synth_Dyadic_Nat_Uns + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + R : constant Net := Get_Net (Right); + L1 : Net; + N : Net; + begin + L1 := Synth_Uresize (Left, Right.Typ.W, Expr); + N := Build_Dyadic (Build_Context, Id, L1, R); + Set_Location (N, Expr); + return Create_Value_Net (N, Create_Res_Bound (Right)); + end Synth_Dyadic_Nat_Uns; + + -- Note: LEFT or RIGHT can be a single bit. + function Synth_Dyadic_Sgn_Sgn + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W); + El_Typ : Type_Acc; + Rtype : Type_Acc; + L1, R1 : Net; + N : Net; + begin + if Left.Typ.Kind = Type_Vector then + El_Typ := Left.Typ.Vec_El; + elsif Right.Typ.Kind = Type_Vector then + El_Typ := Right.Typ.Vec_El; + else + raise Internal_Error; + end if; + Rtype := Create_Vec_Type_By_Length (W, El_Typ); + L1 := Synth_Sresize (Left, W, Expr); + R1 := Synth_Sresize (Right, W, Expr); + N := Build_Dyadic (Build_Context, Id, L1, R1); + Set_Location (N, Expr); + return Create_Value_Net (N, Rtype); + end Synth_Dyadic_Sgn_Sgn; + + function Synth_Dyadic_Sgn_Int + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + L : constant Net := Get_Net (Left); + R1 : Net; + N : Net; + begin + R1 := Synth_Sresize (Right, Left.Typ.W, Expr); + N := Build_Dyadic (Build_Context, Id, L, R1); + Set_Location (N, Expr); + return Create_Value_Net (N, Create_Res_Bound (Left)); + end Synth_Dyadic_Sgn_Int; + + function Synth_Dyadic_Int_Sgn + (Id : Dyadic_Module_Id; Left, Right : Value_Acc; Expr : Node) + return Value_Acc + is + R : constant Net := Get_Net (Right); + L1 : Net; + N : Net; + begin + L1 := Synth_Sresize (Left, Right.Typ.W, Expr); + N := Build_Dyadic (Build_Context, Id, R, L1); + Set_Location (N, Expr); + return Create_Value_Net (N, Create_Res_Bound (Right)); + end Synth_Dyadic_Int_Sgn; + function Synth_Dyadic_Operation (Syn_Inst : Synth_Instance_Acc; Imp : Node; Left_Expr : Node; @@ -394,57 +502,6 @@ package body Synth.Oper is return Create_Value_Net (N, Etype); end Synth_Int_Dyadic; - function Synth_Dyadic_Uns (Id : Dyadic_Module_Id; Is_Res_Vec : Boolean) - return Value_Acc - is - W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W); - El_Typ : Type_Acc; - Rtype : Type_Acc; - L1, R1 : Net; - N : Net; - begin - if Is_Res_Vec then - if Left.Typ.Kind = Type_Vector then - El_Typ := Left.Typ.Vec_El; - elsif Right.Typ.Kind = Type_Vector then - El_Typ := Right.Typ.Vec_El; - else - raise Internal_Error; - end if; - Rtype := Create_Vec_Type_By_Length (W, El_Typ); - else - Rtype := Left.Typ; - end if; - L1 := Synth_Uresize (Left, W, Expr); - R1 := Synth_Uresize (Right, W, Expr); - N := Build_Dyadic (Build_Context, Id, L1, R1); - Set_Location (N, Expr); - return Create_Value_Net (N, Rtype); - end Synth_Dyadic_Uns; - - function Synth_Dyadic_Sgn (Id : Dyadic_Module_Id; Is_Res_Vec : Boolean) - return Value_Acc - is - W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W); - Rtype : Type_Acc; - L1, R1 : Net; - N : Net; - begin - Rtype := Left.Typ; - if Rtype.Kind = Type_Vector then - Rtype := Rtype.Vec_El; - end if; - - if Is_Res_Vec then - Rtype := Create_Vec_Type_By_Length (W, Rtype); - end if; - L1 := Synth_Sresize (Left, W, Expr); - R1 := Synth_Sresize (Right, W, Expr); - N := Build_Dyadic (Build_Context, Id, L1, R1); - Set_Location (N, Expr); - return Create_Value_Net (N, Rtype); - end Synth_Dyadic_Sgn; - function Synth_Compare_Uns_Uns (Id : Compare_Module_Id; Res_Type : Type_Acc) return Value_Acc is @@ -459,54 +516,6 @@ package body Synth.Oper is return Create_Value_Net (N, Res_Type); end Synth_Compare_Uns_Uns; - function Synth_Dyadic_Uns_Nat (Id : Dyadic_Module_Id) return Value_Acc - is - L : constant Net := Get_Net (Left); - R1 : Net; - N : Net; - begin - R1 := Synth_Uresize (Right, Left.Typ.W, Expr); - N := Build_Dyadic (Build_Context, Id, L, R1); - Set_Location (N, Expr); - return Create_Value_Net (N, Create_Res_Bound (Left)); - end Synth_Dyadic_Uns_Nat; - - function Synth_Dyadic_Nat_Uns (Id : Dyadic_Module_Id) return Value_Acc - is - R : constant Net := Get_Net (Right); - L1 : Net; - N : Net; - begin - L1 := Synth_Uresize (Left, Right.Typ.W, Expr); - N := Build_Dyadic (Build_Context, Id, L1, R); - Set_Location (N, Expr); - return Create_Value_Net (N, Create_Res_Bound (Right)); - end Synth_Dyadic_Nat_Uns; - - function Synth_Dyadic_Sgn_Int (Id : Dyadic_Module_Id) return Value_Acc - is - L : constant Net := Get_Net (Left); - R1 : Net; - N : Net; - begin - R1 := Synth_Sresize (Right, Left.Typ.W, Expr); - N := Build_Dyadic (Build_Context, Id, L, R1); - Set_Location (N, Expr); - return Create_Value_Net (N, Create_Res_Bound (Left)); - end Synth_Dyadic_Sgn_Int; - - function Synth_Dyadic_Int_Sgn (Id : Dyadic_Module_Id) return Value_Acc - is - R : constant Net := Get_Net (Right); - L1 : Net; - N : Net; - begin - L1 := Synth_Sresize (Left, Right.Typ.W, Expr); - N := Build_Dyadic (Build_Context, Id, R, L1); - Set_Location (N, Expr); - return Create_Value_Net (N, Create_Res_Bound (Right)); - end Synth_Dyadic_Int_Sgn; - function Synth_Compare_Sgn_Sgn (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Value_Acc is @@ -811,23 +820,23 @@ package body Synth.Oper is when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Int => -- "+" (Unsigned, Natural) - return Synth_Dyadic_Uns_Nat (Id_Add); + return Synth_Dyadic_Uns_Nat (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns => -- "+" (Natural, Unsigned) - return Synth_Dyadic_Nat_Uns (Id_Add); + return Synth_Dyadic_Nat_Uns (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns | Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Log | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Slv | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Slv => -- "+" (Unsigned, Unsigned) - return Synth_Dyadic_Uns (Id_Add, True); + return Synth_Dyadic_Uns_Uns (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int => -- "+" (Signed, Integer) - return Synth_Dyadic_Sgn_Int (Id_Add); + return Synth_Dyadic_Sgn_Int (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Add_Int_Sgn => -- "+" (Integer, Signed) - return Synth_Dyadic_Int_Sgn (Id_Add); + return Synth_Dyadic_Int_Sgn (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn | Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log | Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn @@ -837,30 +846,30 @@ package body Synth.Oper is | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Sgn_Slv | Iir_Predefined_Ieee_Std_Logic_Signed_Add_Slv_Slv => -- "+" (Signed, Signed) - return Synth_Dyadic_Sgn (Id_Add, True); + return Synth_Dyadic_Sgn_Sgn (Id_Add, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Int => -- "-" (Unsigned, Natural) - return Synth_Dyadic_Uns_Nat (Id_Sub); + return Synth_Dyadic_Uns_Nat (Id_Sub, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Slv | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Log_Slv | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Log => -- "-" (Unsigned, Unsigned) - return Synth_Dyadic_Uns (Id_Sub, True); + return Synth_Dyadic_Uns_Uns (Id_Sub, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Int => -- "-" (Signed, Integer) - return Synth_Dyadic_Sgn_Int (Id_Sub); + return Synth_Dyadic_Sgn_Int (Id_Sub, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Sub_Int_Sgn => -- "-" (Integer, Signed) - return Synth_Dyadic_Int_Sgn (Id_Sub); + return Synth_Dyadic_Int_Sgn (Id_Sub, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Sgn | Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log | Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn => -- "-" (Signed, Signed) - return Synth_Dyadic_Sgn (Id_Sub, True); + return Synth_Dyadic_Sgn_Sgn (Id_Sub, Left, Right, Expr); when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Sgn_Sgn @@ -1429,11 +1438,22 @@ package body Synth.Oper is return Create_Value_Net (Arg_Net, Create_Vec_Type_By_Length (Size, Logic_Type)); end Synth_Conv_Vector; + + L : Value_Acc; + R : Value_Acc; begin Param1 := Inter_Chain; if Param1 /= Null_Node then + L := Get_Value (Subprg_Inst, Param1); Param2 := Get_Chain (Inter_Chain); + if Param2 /= Null_Node then + R := Get_Value (Subprg_Inst, Param2); + else + R := null; + end if; else + L := null; + R := null; Param2 := Null_Node; end if; @@ -1443,7 +1463,7 @@ package body Synth.Oper is Clk : Net; Edge : Net; begin - Clk := Get_Net (Get_Value (Subprg_Inst, Param1)); + Clk := Get_Net (L); Edge := Build_Edge (Ctxt, Clk); return Create_Value_Net (Edge, Boolean_Type); end; @@ -1452,7 +1472,7 @@ package body Synth.Oper is Clk : Net; Edge : Net; begin - Clk := Get_Net (Get_Value (Subprg_Inst, Param1)); + Clk := Get_Net (L); Clk := Build_Monadic (Ctxt, Id_Not, Clk); Edge := Build_Edge (Ctxt, Clk); return Create_Value_Net (Edge, Boolean_Type); @@ -1462,26 +1482,16 @@ package body Synth.Oper is -- Always false. return Create_Value_Discrete (0, Boolean_Type); when Iir_Predefined_Ieee_1164_To_Bitvector => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - pragma Unreferenced (R); - begin - if Is_Static (L) then - raise Internal_Error; - end if; - return Create_Value_Net (Get_Net (L), Create_Res_Bound (L)); - end; + if Is_Static (L) then + raise Internal_Error; + end if; + return Create_Value_Net (Get_Net (L), Create_Res_Bound (L)); when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Suv | Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - begin - if Is_Static (L) then - raise Internal_Error; - end if; - return Create_Value_Net (Get_Net (L), Create_Res_Bound (L)); - end; + if Is_Static (L) then + raise Internal_Error; + end if; + return Create_Value_Net (Get_Net (L), Create_Res_Bound (L)); when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Int => return Synth_Conv_Vector (False); @@ -1497,76 +1507,72 @@ package body Synth.Oper is Get_Value_Type (Subprg_Inst, Get_Type (Imp)); begin return Create_Value_Net - (Synth_Uresize (Get_Net (Get_Value (Subprg_Inst, Param1)), - Int_Type.W, Expr), - Int_Type); + (Synth_Uresize (Get_Net (L), Int_Type.W, Expr), Int_Type); end; when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat => declare - V : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - Sz : constant Value_Acc := Get_Value (Subprg_Inst, Param2); W : Width; begin - if not Is_Static (Sz) then + if not Is_Static (R) then Error_Msg_Synth (+Expr, "size must be constant"); return null; end if; - W := Uns32 (Sz.Scal); + W := Uns32 (R.Scal); return Create_Value_Net - (Synth_Uresize (Get_Net (V), W, Expr), + (Synth_Uresize (Get_Net (L), W, Expr), Create_Vec_Type_By_Length (W, Logic_Type)); end; when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat => declare - V : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - Sz : constant Value_Acc := Get_Value (Subprg_Inst, Param2); W : Width; begin - if not Is_Static (Sz) then + if not Is_Static (R) then Error_Msg_Synth (+Expr, "size must be constant"); return null; end if; - W := Uns32 (Sz.Scal); + W := Uns32 (R.Scal); return Create_Value_Net - (Build2_Sresize (Ctxt, Get_Net (V), W, Get_Location (Expr)), + (Build2_Sresize (Ctxt, Get_Net (L), W, Get_Location (Expr)), Create_Vec_Type_By_Length (W, Logic_Type)); end; when Iir_Predefined_Ieee_Numeric_Std_Shl_Uns_Nat | Iir_Predefined_Ieee_Numeric_Std_Shl_Sgn_Nat => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - begin - return Synth_Shift_Rotate (Id_Lsl, L, R, Expr); - end; + return Synth_Shift_Rotate (Id_Lsl, L, R, Expr); when Iir_Predefined_Ieee_Numeric_Std_Shr_Uns_Nat => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - begin - return Synth_Shift_Rotate (Id_Lsr, L, R, Expr); - end; + return Synth_Shift_Rotate (Id_Lsr, L, R, Expr); when Iir_Predefined_Ieee_Numeric_Std_Shr_Sgn_Nat => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - begin - return Synth_Shift_Rotate (Id_Asr, L, R, Expr); - end; + return Synth_Shift_Rotate (Id_Asr, L, R, Expr); when Iir_Predefined_Ieee_Numeric_Std_Rol_Uns_Nat => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - begin - return Synth_Shift_Rotate (Id_Rol, L, R, Expr); - end; + return Synth_Shift_Rotate (Id_Rol, L, R, Expr); when Iir_Predefined_Ieee_Numeric_Std_Ror_Uns_Nat => - declare - L : constant Value_Acc := Get_Value (Subprg_Inst, Param1); - R : constant Value_Acc := Get_Value (Subprg_Inst, Param2); - begin - return Synth_Shift_Rotate (Id_Ror, L, R, Expr); - end; + return Synth_Shift_Rotate (Id_Ror, L, R, Expr); + + when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Uns => + return Synth_Dyadic_Uns_Uns (Id_Umin, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Nat => + return Synth_Dyadic_Uns_Nat (Id_Umin, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Min_Nat_Uns => + return Synth_Dyadic_Nat_Uns (Id_Umin, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Sgn => + return Synth_Dyadic_Sgn_Sgn (Id_Smin, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Int => + return Synth_Dyadic_Sgn_Int (Id_Smin, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Min_Int_Sgn => + return Synth_Dyadic_Int_Sgn (Id_Smin, L, R, Expr); + + when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Uns => + return Synth_Dyadic_Uns_Uns (Id_Umax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Nat => + return Synth_Dyadic_Uns_Nat (Id_Umax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Max_Nat_Uns => + return Synth_Dyadic_Nat_Uns (Id_Umax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Sgn => + return Synth_Dyadic_Sgn_Sgn (Id_Smax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Int => + return Synth_Dyadic_Sgn_Int (Id_Smax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Max_Int_Sgn => + return Synth_Dyadic_Int_Sgn (Id_Smax, L, R, Expr); + when Iir_Predefined_Ieee_Numeric_Std_Match_Suv | Iir_Predefined_Ieee_Numeric_Std_Match_Slv => declare |