aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-vhdl_oper.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-vhdl_oper.adb')
-rw-r--r--src/synth/synth-vhdl_oper.adb2151
1 files changed, 2151 insertions, 0 deletions
diff --git a/src/synth/synth-vhdl_oper.adb b/src/synth/synth-vhdl_oper.adb
new file mode 100644
index 000000000..9aaf725d1
--- /dev/null
+++ b/src/synth/synth-vhdl_oper.adb
@@ -0,0 +1,2151 @@
+-- Operations synthesis.
+-- Copyright (C) 2019 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- 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 Types_Utils; use Types_Utils;
+with Mutils;
+
+with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164;
+with Vhdl.Errors; use Vhdl.Errors;
+with Vhdl.Utils; use Vhdl.Utils;
+
+with Areapools;
+
+with Netlists; use Netlists;
+with Netlists.Gates; use Netlists.Gates;
+with Netlists.Builders; use Netlists.Builders;
+with Netlists.Folds; use Netlists.Folds;
+with Netlists.Utils;
+
+with Synth.Errors; use Synth.Errors;
+with Synth.Stmts; use Synth.Stmts;
+with Synth.Expr; use Synth.Expr;
+with Synth.Source;
+with Synth.Static_Oper; use Synth.Static_Oper;
+
+package body Synth.Vhdl_Oper is
+ procedure Set_Location (N : Net; Loc : Node)
+ renames Standard.Synth.Source.Set_Location;
+
+ function Synth_Uresize
+ (Ctxt : Context_Acc; Val : Valtyp; W : Width; Loc : Node) return Net
+ is
+ Res : Net;
+ begin
+ if Is_Static (Val.Val) and then Val.Typ.Kind = Type_Discrete then
+ if Val.Typ.Drange.Is_Signed and then Read_Discrete (Val) < 0 then
+ -- TODO.
+ raise Internal_Error;
+ else
+ Res := Build2_Const_Uns
+ (Ctxt, To_Uns64 (Read_Discrete (Val)), W);
+ end if;
+ Set_Location (Res, Loc);
+ return Res;
+ end if;
+ return Build2_Uresize (Ctxt, Get_Net (Ctxt, Val), W, Get_Location (Loc));
+ end Synth_Uresize;
+
+ function Synth_Sresize
+ (Ctxt : Context_Acc; Val : Valtyp; W : Width; Loc : Node) return Net
+ is
+ Res : Net;
+ begin
+ if Is_Static (Val.Val) and then Val.Typ.Kind = Type_Discrete then
+ if Val.Typ.Drange.Is_Signed then
+ Res := Build2_Const_Int (Ctxt, Read_Discrete (Val), W);
+ else
+ -- TODO.
+ raise Internal_Error;
+ end if;
+ Set_Location (Res, Loc);
+ return Res;
+ end if;
+ return Build2_Sresize (Ctxt, Get_Net (Ctxt, Val), W, Get_Location (Loc));
+ end Synth_Sresize;
+
+ function Synth_Resize (Ctxt : Context_Acc;
+ Val : Valtyp;
+ W : Width;
+ Sgn : Boolean;
+ Loc : Node) return Net is
+ begin
+ if Sgn then
+ return Synth_Sresize (Ctxt, Val, W, Loc);
+ else
+ return Synth_Uresize (Ctxt, Val, W, Loc);
+ end if;
+ end Synth_Resize;
+
+ function Synth_Bit_Eq_Const
+ (Ctxt : Context_Acc; Cst : Valtyp; Expr : Valtyp; Loc : Node)
+ return Valtyp
+ is
+ Val : Uns32;
+ Zx : Uns32;
+ N : Net;
+ begin
+ if Is_Static (Expr.Val) then
+ return Create_Value_Discrete
+ (Boolean'Pos (Read_Discrete (Cst) = Read_Discrete (Expr)),
+ Boolean_Type);
+ end if;
+
+ To_Logic (Read_Discrete (Cst), Cst.Typ, Val, Zx);
+ if Zx /= 0 then
+ -- Equal unknown -> return X
+ N := Build_Const_UL32 (Ctxt, 0, 1, 1);
+ Set_Location (N, Loc);
+ return Create_Value_Net (N, Boolean_Type);
+ elsif Val = 1 then
+ -- The result type is a boolean; convert if needed.
+ if Expr.Typ.Kind = Type_Logic then
+ return Create_Value_Net (Get_Net (Ctxt, Expr), Boolean_Type);
+ else
+ pragma Assert (Expr.Typ.Kind = Type_Bit);
+ return Expr;
+ end if;
+ else
+ pragma Assert (Val = 0);
+ N := Build_Monadic (Ctxt, Id_Not, Get_Net (Ctxt, Expr));
+ Set_Location (N, Loc);
+ return Create_Value_Net (N, Boolean_Type);
+ end if;
+ end Synth_Bit_Eq_Const;
+
+ -- Create the result range of an operator. According to the ieee standard,
+ -- the range is LEN-1 downto 0.
+ function Create_Res_Bound (Prev : Valtyp) return Type_Acc
+ is
+ Res : Type_Acc;
+ begin
+ Res := Prev.Typ;
+
+ case Res.Kind is
+ when Type_Vector =>
+ if Res.Vbound.Dir = Dir_Downto
+ and then Res.Vbound.Right = 0
+ then
+ -- Normalized range
+ return Res;
+ end if;
+ return Create_Vec_Type_By_Length (Res.W, Res.Vec_El);
+
+ when Type_Slice =>
+ return Create_Vec_Type_By_Length (Res.W, Res.Slice_El);
+
+ when Type_Unbounded_Vector =>
+ raise Internal_Error;
+
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Create_Res_Bound;
+
+ function Create_Bounds_From_Length
+ (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;
+ end Create_Bounds_From_Length;
+
+ -- Do a match comparison between CST and OPER.
+ -- Return No_Net if CST has incorrect value.
+ function Synth_Match (Ctxt : Context_Acc;
+ Cst : Valtyp;
+ Oper : Valtyp;
+ Expr : Node;
+ Op : Compare_Module_Id := Id_Eq) return Net
+ is
+ Wd : constant Width := Cst.Typ.W;
+ pragma Assert (Wd > 0);
+ Nwords : constant Natural := Natural ((Wd + 31) / 32);
+ Mask : Uns32_Arr_Acc;
+ Vals : Uns32_Arr_Acc;
+ Boff : Natural;
+ Woff : Natural;
+ B : Uns32;
+ M : Uns32;
+ Nv : Net;
+ Nm : Net;
+ Res : Net;
+ begin
+ -- Flatten 0/1 DC.
+ Mask := new Uns32_Arr'(0 .. Nwords - 1 => 0);
+ Vals := new Uns32_Arr'(0 .. Nwords - 1 => 0);
+
+ Boff := 0;
+ Woff := 0;
+ for I in reverse 1 .. Vec_Length (Cst.Typ) loop
+ case Read_U8 (Cst.Val.Mem + Size_Type (I - 1)) is
+ when Std_Logic_0_Pos
+ | Std_Logic_L_Pos =>
+ B := 0;
+ M := 1;
+ when Std_Logic_1_Pos
+ | Std_Logic_H_Pos =>
+ B := 1;
+ M := 1;
+ when Std_Logic_U_Pos
+ | Std_Logic_X_Pos
+ | Std_Logic_Z_Pos
+ | Std_Logic_W_Pos =>
+ -- Never match
+ -- FIXME: warning ?
+ Unchecked_Deallocate (Mask);
+ Unchecked_Deallocate (Vals);
+ return No_Net;
+ when Std_Logic_D_Pos =>
+ B := 0;
+ M := 0;
+ when others =>
+ raise Internal_Error;
+ end case;
+ Mask (Woff) := Mask (Woff) or Shift_Left (M, Boff);
+ Vals (Woff) := Vals (Woff) or Shift_Left (B, Boff);
+ Boff := Boff + 1;
+ if Boff = 32 then
+ Boff := 0;
+ Woff := Woff + 1;
+ end if;
+ end loop;
+
+ -- Generate and + eq
+ Nv := Build2_Const_Vec (Ctxt, Wd, Vals.all);
+ Set_Location (Nv, Expr);
+ Unchecked_Deallocate (Vals);
+ Nm := Build2_Const_Vec (Ctxt, Wd, Mask.all);
+ Set_Location (Nm, Expr);
+ Unchecked_Deallocate (Mask);
+ Res := Build_Dyadic (Ctxt, Id_And, Get_Net (Ctxt, Oper), Nm);
+ Set_Location (Res, Expr);
+ Res := Build_Compare (Ctxt, Op, Res, Nv);
+ Set_Location (Res, Expr);
+
+ return Res;
+ end Synth_Match;
+
+ -- Note: LEFT or RIGHT can be a single bit.
+ function Synth_Dyadic_Xxx_Xxx (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ W : Width;
+ Left, Right : Valtyp;
+ Lsgn, Rsgn : Boolean;
+ Expr : Node) return Valtyp
+ is
+ El_Typ : Type_Acc;
+ Rtype : Type_Acc;
+ L1, R1 : Net;
+ N : Net;
+ begin
+ -- Note: LEFT or RIGHT can be a single bit.
+ 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_Resize (Ctxt, Left, W, Lsgn, Expr);
+ R1 := Synth_Resize (Ctxt, Right, W, Rsgn, Expr);
+ N := Build_Dyadic (Ctxt, Id, L1, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Rtype);
+ end Synth_Dyadic_Xxx_Xxx;
+
+ function Synth_Dyadic_Uns_Uns (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp is
+ begin
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W),
+ Left, Right, False, False, Expr);
+ end Synth_Dyadic_Uns_Uns;
+
+ function Synth_Dyadic_Sgn_Sgn (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp is
+ begin
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W),
+ Left, Right, True, True, Expr);
+ end Synth_Dyadic_Sgn_Sgn;
+
+ -- For std_logic_arith
+ function Synth_Dyadic_Uns_Sgn_Sgn (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp is
+ begin
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W + 1, Right.Typ.W),
+ Left, Right, False, True, Expr);
+ end Synth_Dyadic_Uns_Sgn_Sgn;
+
+ -- For std_logic_arith
+ function Synth_Dyadic_Sgn_Uns_Sgn (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp is
+ begin
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W + 1),
+ Left, Right, True, False, Expr);
+ end Synth_Dyadic_Sgn_Uns_Sgn;
+
+ function Synth_Dyadic_Uns_Nat (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ L : constant Net := Get_Net (Ctxt, Left);
+ R1 : Net;
+ N : Net;
+ begin
+ R1 := Synth_Uresize (Ctxt, Right, Left.Typ.W, Expr);
+ N := Build_Dyadic (Ctxt, 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 (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ R : constant Net := Get_Net (Ctxt, Right);
+ L1 : Net;
+ N : Net;
+ begin
+ L1 := Synth_Uresize (Ctxt, Left, Right.Typ.W, Expr);
+ N := Build_Dyadic (Ctxt, 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 (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ L : constant Net := Get_Net (Ctxt, Left);
+ R1 : Net;
+ N : Net;
+ begin
+ R1 := Synth_Sresize (Ctxt, Right, Left.Typ.W, Expr);
+ N := Build_Dyadic (Ctxt, 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 (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ R : constant Net := Get_Net (Ctxt, Right);
+ L1 : Net;
+ N : Net;
+ begin
+ L1 := Synth_Sresize (Ctxt, Left, Right.Typ.W, Expr);
+ N := Build_Dyadic (Ctxt, Id, R, L1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Right));
+ end Synth_Dyadic_Int_Sgn;
+
+ function Synth_Dyadic_Vec_Log (Ctxt : Context_Acc;
+ Id : Dyadic_Module_Id;
+ Vec, Log : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ V : constant Net := Get_Net (Ctxt, Vec);
+ L : constant Net := Get_Net (Ctxt, Log);
+ Wd : constant Width := Get_Width (V);
+ Lv : Net;
+ Res : Net;
+ begin
+ Lv := Build2_Sresize (Ctxt, L, Wd, Get_Location (Expr));
+ Res := Build_Dyadic (Ctxt, Id, V, Lv);
+ Set_Location (Res, Expr);
+ return Create_Value_Net (Res, Create_Res_Bound (Vec));
+ end Synth_Dyadic_Vec_Log;
+
+ function Synth_Compare_Xxx_Xxx (Ctxt : Context_Acc;
+ Id : Compare_Module_Id;
+ W : Width;
+ Left, Right : Valtyp;
+ Lsgn, Rsgn : Boolean;
+ Res_Typ : Type_Acc;
+ Expr : Node) return Valtyp
+ is
+ L1, R1 : Net;
+ N : Net;
+ begin
+ L1 := Synth_Resize (Ctxt, Left, W, Lsgn, Expr);
+ R1 := Synth_Resize (Ctxt, Right, W, Rsgn, Expr);
+ N := Build2_Compare (Ctxt, Id, L1, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Res_Typ);
+ end Synth_Compare_Xxx_Xxx;
+
+ function Synth_Dyadic_Operation (Syn_Inst : Synth_Instance_Acc;
+ Imp : Node;
+ Left_Expr : Node;
+ Right_Expr : Node;
+ Expr : Node) return Valtyp
+ is
+ Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
+ Def : constant Iir_Predefined_Functions :=
+ Get_Implicit_Definition (Imp);
+ Inter_Chain : constant Node :=
+ Get_Interface_Declaration_Chain (Imp);
+ Expr_Type : constant Node := Get_Type (Expr);
+ Left_Type : constant Node := Get_Type (Inter_Chain);
+ Right_Type : constant Node := Get_Type (Get_Chain (Inter_Chain));
+ Left_Typ : constant Type_Acc :=
+ Get_Subtype_Object (Syn_Inst, Left_Type);
+ Right_Typ : constant Type_Acc :=
+ Get_Subtype_Object (Syn_Inst, Right_Type);
+ Expr_Typ : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Expr_Type);
+ Srec : Memtyp;
+ Left : Valtyp;
+ Right : Valtyp;
+
+ function Synth_Bit_Dyadic (Id : Dyadic_Module_Id) return Valtyp
+ is
+ N : Net;
+ begin
+ N := Build_Dyadic
+ (Ctxt, Id, Get_Net (Ctxt, Left), Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Left.Typ);
+ end Synth_Bit_Dyadic;
+
+ function Synth_Compare (Id : Compare_Module_Id; Res_Type : Type_Acc)
+ return Valtyp
+ is
+ N : Net;
+ begin
+ pragma Assert (Left_Type = Right_Type);
+ pragma Assert (Res_Type = Expr_Typ);
+ N := Build2_Compare
+ (Ctxt, Id, Get_Net (Ctxt, Left), Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Res_Type);
+ end Synth_Compare;
+
+ function Synth_Minmax (Id : Compare_Module_Id) return Valtyp
+ is
+ L : constant Net := Get_Net (Ctxt, Left);
+ R : constant Net := Get_Net (Ctxt, Right);
+ Sel, N : Net;
+ begin
+ pragma Assert (Left_Type = Right_Type);
+ Sel := Build2_Compare (Ctxt, Id, L, R);
+ Set_Location (Sel, Expr);
+ N := Build_Mux2 (Ctxt, Sel, R, L);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Expr_Typ);
+ end Synth_Minmax;
+
+ function Synth_Compare_Array (Id : Compare_Module_Id;
+ Res_Type : Type_Acc) return Valtyp
+ is
+ N : Net;
+ begin
+ if Left.Typ.Kind = Type_Vector then
+ Warning_Msg_Synth
+ (+Expr, "comparing non-numeric vector is unexpected");
+ if Left.Typ.W = Right.Typ.W then
+ N := Build2_Compare
+ (Ctxt, Id, Get_Net (Ctxt, Left), Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Res_Type);
+ elsif Left.Typ.W < Right.Typ.W then
+ -- TODO: truncate right, compare using id_eq.
+ raise Internal_Error;
+ else
+ -- TODO: truncate left, compare using id.
+ raise Internal_Error;
+ end if;
+ else
+ raise Internal_Error;
+ end if;
+ end Synth_Compare_Array;
+
+ function Synth_Compare_Uns_Uns
+ (Id : Compare_Module_Id; Res_Type : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W),
+ Left, Right, False, False, Res_Type, Expr);
+ end Synth_Compare_Uns_Uns;
+
+ function Synth_Compare_Sgn_Sgn
+ (Id : Compare_Module_Id; Res_Type : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W),
+ Left, Right, True, True, Res_Type, Expr);
+ end Synth_Compare_Sgn_Sgn;
+
+ -- For std_logic_arith
+ function Synth_Compare_Uns_Sgn
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W + 1, Right.Typ.W),
+ Left, Right, False, True, Res_Typ, Expr);
+ end Synth_Compare_Uns_Sgn;
+
+ -- For std_logic_arith
+ function Synth_Compare_Sgn_Uns
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Width'Max (Left.Typ.W, Right.Typ.W + 1),
+ Left, Right, True, False, Res_Typ, Expr);
+ end Synth_Compare_Sgn_Uns;
+
+ function Synth_Compare_Uns_Nat
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Left.Typ.W,
+ Left, Right, False, False, Res_Typ, Expr);
+ end Synth_Compare_Uns_Nat;
+
+ function Synth_Compare_Nat_Uns
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Right.Typ.W,
+ Left, Right, False, False, Res_Typ, Expr);
+ end Synth_Compare_Nat_Uns;
+
+ function Synth_Compare_Sgn_Int
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Left.Typ.W,
+ Left, Right, True, True, Res_Typ, Expr);
+ end Synth_Compare_Sgn_Int;
+
+ function Synth_Compare_Int_Sgn
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Right.Typ.W,
+ Left, Right, True, True, Res_Typ, Expr);
+ end Synth_Compare_Int_Sgn;
+
+ -- For std_logic_arith
+ function Synth_Compare_Uns_Int
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Left.Typ.W + 1,
+ Left, Right, False, True, Res_Typ, Expr);
+ end Synth_Compare_Uns_Int;
+
+ -- For std_logic_arith
+ function Synth_Compare_Int_Uns
+ (Id : Compare_Module_Id; Res_Typ : Type_Acc) return Valtyp is
+ begin
+ return Synth_Compare_Xxx_Xxx
+ (Ctxt, Id, Right.Typ.W + 1,
+ Left, Right, True, False, Res_Typ, Expr);
+ end Synth_Compare_Int_Uns;
+
+ function Synth_Vec_Dyadic (Id : Dyadic_Module_Id) return Valtyp
+ is
+ N : Net;
+ begin
+ if Left.Typ.W /= Right.Typ.W then
+ Error_Msg_Synth (+Expr, "operands don't have the same length");
+ return No_Valtyp;
+ end if;
+ N := Build_Dyadic (Ctxt, Id,
+ Get_Net (Ctxt, Left), Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Vec_Dyadic;
+
+ function Synth_Int_Dyadic (Id : Dyadic_Module_Id) return Valtyp
+ is
+ Etype : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Expr_Type);
+ N : Net;
+ begin
+ N := Build_Dyadic
+ (Ctxt, Id, Get_Net (Ctxt, Left), Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Etype);
+ end Synth_Int_Dyadic;
+
+ type Oper_Kind is (Oper_Left, Oper_Right);
+
+ function Synth_Udivmod (Id : Dyadic_Module_Id; Vec : Oper_Kind)
+ return Valtyp
+ is
+ W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
+ L1, R1 : Net;
+ Res_Typ : Type_Acc;
+ N : Net;
+ begin
+ L1 := Synth_Uresize (Ctxt, Left, W, Expr);
+ R1 := Synth_Uresize (Ctxt, Right, W, Expr);
+ case Vec is
+ when Oper_Left =>
+ Res_Typ := Left.Typ;
+ when Oper_Right =>
+ Res_Typ := Right.Typ;
+ end case;
+ Res_Typ := Create_Vec_Type_By_Length (Res_Typ.W, Res_Typ.Vec_El);
+ N := Build_Dyadic (Ctxt, Id, L1, R1);
+ Set_Location (N, Expr);
+ N := Build2_Uresize (Ctxt, N, Res_Typ.W, Get_Location (Expr));
+ return Create_Value_Net (N, Res_Typ);
+ end Synth_Udivmod;
+
+ function Synth_Sdivmod (Id : Dyadic_Module_Id; Vec : Oper_Kind)
+ return Valtyp
+ is
+ W : constant Width := Width'Max (Left.Typ.W, Right.Typ.W);
+ L1, R1 : Net;
+ Res_Typ : Type_Acc;
+ N : Net;
+ begin
+ L1 := Synth_Sresize (Ctxt, Left, W, Expr);
+ R1 := Synth_Sresize (Ctxt, Right, W, Expr);
+ case Vec is
+ when Oper_Left =>
+ Res_Typ := Left.Typ;
+ when Oper_Right =>
+ Res_Typ := Right.Typ;
+ end case;
+ Res_Typ := Create_Vec_Type_By_Length (Res_Typ.W, Res_Typ.Vec_El);
+ N := Build_Dyadic (Ctxt, Id, L1, R1);
+ Set_Location (N, Expr);
+ N := Build2_Sresize (Ctxt, N, Res_Typ.W, Get_Location (Expr));
+ return Create_Value_Net (N, Res_Typ);
+ end Synth_Sdivmod;
+
+ function Synth_Shift (Sh_Pos : Module_Id; Sh_Neg : Module_Id)
+ return Valtyp
+ is
+ L1, R1 : Net;
+ N, Nn, Nr1, Cond : Net;
+ begin
+ L1 := Get_Net (Ctxt, Left);
+ R1 := Get_Net (Ctxt, Right);
+
+ -- Handle the case when the RHS is positive.
+ N := Build_Shift_Rotate (Ctxt, Sh_Pos, L1, R1);
+ Set_Location (N, Expr);
+
+ if not Is_Positive (Right) then
+ -- If we cannot trivially prove that the RHS is positive, also
+ -- handle the case when it could be negative.
+ -- At worst, the optimizer will remove that part.
+ Nr1 := Build_Monadic (Ctxt, Id_Neg, R1);
+ Set_Location (Nr1, Expr);
+ Nn := Build_Shift_Rotate (Ctxt, Sh_Neg, L1, Nr1);
+ Set_Location (Nn, Expr);
+
+ -- Extract the sign bit.
+ Cond := Build_Extract (Ctxt, R1, Get_Width (R1) - 1, 1);
+ Set_Location (Cond, Expr);
+
+ N := Build_Mux2 (Ctxt, Cond, N, Nn);
+ Set_Location (N, Expr);
+ end if;
+
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Shift;
+
+ function Synth_Rotation (Id : Module_Id) return Valtyp
+ is
+ Amt : Int64;
+ Ww : Width;
+ L1, R1 : Net;
+ N : Net;
+ begin
+ if Is_Static_Val (Right.Val) then
+ Amt := Get_Static_Discrete (Right);
+ if Amt < 0 then
+ raise Internal_Error;
+ end if;
+ Amt := Amt mod Int64 (Left.Typ.W);
+ R1 := Build_Const_UB32 (Ctxt, Uns32 (Amt), Right.Typ.W);
+ Set_Location (R1, Right_Expr);
+ elsif not Is_Positive (Right) then
+ Error_Msg_Synth (+Expr, "rotation quantity must be unsigned");
+ return Left;
+ else
+ R1 := Get_Net (Ctxt, Right);
+ Ww := Netlists.Utils.Clog2 (Left.Typ.W);
+ if Right.Typ.W >= Ww then
+ if Mutils.Is_Power2 (Uns64 (Left.Typ.W)) then
+ R1 := Build2_Trunc (Ctxt, Id_Utrunc, R1, Ww, +Expr);
+ else
+ Error_Msg_Synth
+ (+Expr, "vector length of rotation must be a power of 2");
+ return Left;
+ end if;
+ end if;
+ end if;
+ L1 := Get_Net (Ctxt, Left);
+ N := Build_Shift_Rotate (Ctxt, Id, L1, R1);
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Rotation;
+ begin
+ Left := Synth_Expression_With_Type (Syn_Inst, Left_Expr, Left_Typ);
+ if Left = No_Valtyp then
+ return No_Valtyp;
+ end if;
+ Left := Synth_Subtype_Conversion (Ctxt, Left, Left_Typ, False, Expr);
+ Right := Synth_Expression_With_Type (Syn_Inst, Right_Expr, Right_Typ);
+ if Right = No_Valtyp then
+ return No_Valtyp;
+ end if;
+ Right := Synth_Subtype_Conversion (Ctxt, Right, Right_Typ, False, Expr);
+
+ if Is_Static_Val (Left.Val) and Is_Static_Val (Right.Val) then
+ Srec := Synth_Static_Dyadic_Predefined
+ (Syn_Inst, Imp,
+ Get_Value_Memtyp (Left), Get_Value_Memtyp (Right), Expr);
+ if Srec = Null_Memtyp then
+ return No_Valtyp;
+ end if;
+ return Create_Value_Memtyp (Srec);
+ end if;
+
+ Strip_Const (Left);
+ Strip_Const (Right);
+
+ case Def is
+ when Iir_Predefined_Error =>
+ return No_Valtyp;
+
+ when Iir_Predefined_Bit_And
+ | Iir_Predefined_Boolean_And
+ | Iir_Predefined_Ieee_1164_Scalar_And =>
+ return Synth_Bit_Dyadic (Id_And);
+ when Iir_Predefined_Bit_Xor
+ | Iir_Predefined_Boolean_Xor
+ | Iir_Predefined_Ieee_1164_Scalar_Xor =>
+ return Synth_Bit_Dyadic (Id_Xor);
+ when Iir_Predefined_Bit_Or
+ | Iir_Predefined_Boolean_Or
+ | Iir_Predefined_Ieee_1164_Scalar_Or =>
+ return Synth_Bit_Dyadic (Id_Or);
+ when Iir_Predefined_Bit_Nor
+ | Iir_Predefined_Ieee_1164_Scalar_Nor =>
+ return Synth_Bit_Dyadic (Id_Nor);
+ when Iir_Predefined_Bit_Nand
+ | Iir_Predefined_Boolean_Nand
+ | Iir_Predefined_Ieee_1164_Scalar_Nand =>
+ return Synth_Bit_Dyadic (Id_Nand);
+ when Iir_Predefined_Bit_Xnor
+ | Iir_Predefined_Boolean_Xnor
+ | Iir_Predefined_Ieee_1164_Scalar_Xnor =>
+ return Synth_Bit_Dyadic (Id_Xnor);
+
+ when Iir_Predefined_Ieee_1164_Vector_And
+ | Iir_Predefined_Ieee_Numeric_Std_And_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_And_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_And);
+ when Iir_Predefined_Ieee_1164_Vector_Or
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_Or);
+ when Iir_Predefined_Ieee_1164_Vector_Nand
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_Nand);
+ when Iir_Predefined_Ieee_1164_Vector_Nor
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_Nor);
+ when Iir_Predefined_TF_Array_Xor
+ | Iir_Predefined_Ieee_1164_Vector_Xor
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_Xor);
+ when Iir_Predefined_Ieee_1164_Vector_Xnor
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn_Sgn =>
+ return Synth_Vec_Dyadic (Id_Xnor);
+
+ when Iir_Predefined_Ieee_1164_And_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_And, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_And_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_And, Right, Left, Expr);
+ when Iir_Predefined_Ieee_1164_Nand_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Nand, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_Nand_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Nand, Right, Left, Expr);
+ when Iir_Predefined_Ieee_1164_Or_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Or, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_Or_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Or, Right, Left, Expr);
+ when Iir_Predefined_Ieee_1164_Nor_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Nor, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_Nor_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Nor, Right, Left, Expr);
+ when Iir_Predefined_Ieee_1164_Xor_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Xor, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_Xor_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Xor, Right, Left, Expr);
+ when Iir_Predefined_Ieee_1164_Xnor_Suv_Log =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Xnor, Left, Right, Expr);
+ when Iir_Predefined_Ieee_1164_Xnor_Log_Suv =>
+ return Synth_Dyadic_Vec_Log (Ctxt, Id_Xnor, Right, Left, Expr);
+
+ when Iir_Predefined_Enum_Equality =>
+ if Left_Typ = Bit_Type
+ or else Left_Typ = Logic_Type
+ then
+ if Is_Static (Left.Val) then
+ return Synth_Bit_Eq_Const (Ctxt, Left, Right, Expr);
+ elsif Is_Static (Right.Val) then
+ return Synth_Bit_Eq_Const (Ctxt, Right, Left, Expr);
+ end if;
+ end if;
+ return Synth_Compare (Id_Eq, Boolean_Type);
+ when Iir_Predefined_Enum_Inequality =>
+ -- TODO: Optimize ?
+ return Synth_Compare (Id_Ne, Boolean_Type);
+ when Iir_Predefined_Enum_Less_Equal =>
+ return Synth_Compare (Id_Ule, Boolean_Type);
+ when Iir_Predefined_Enum_Less =>
+ return Synth_Compare (Id_Ult, Boolean_Type);
+ when Iir_Predefined_Enum_Greater_Equal =>
+ return Synth_Compare (Id_Uge, Boolean_Type);
+ when Iir_Predefined_Enum_Greater =>
+ return Synth_Compare (Id_Ugt, Boolean_Type);
+
+ when Iir_Predefined_Std_Ulogic_Match_Equality =>
+ return Synth_Compare (Id_Eq, Logic_Type);
+ when Iir_Predefined_Std_Ulogic_Match_Inequality =>
+ return Synth_Compare (Id_Ne, Logic_Type);
+ when Iir_Predefined_Std_Ulogic_Match_Less =>
+ return Synth_Compare (Id_Ult, Logic_Type);
+ when Iir_Predefined_Std_Ulogic_Match_Less_Equal =>
+ return Synth_Compare (Id_Ule, Logic_Type);
+ when Iir_Predefined_Std_Ulogic_Match_Greater =>
+ return Synth_Compare (Id_Ugt, Logic_Type);
+ when Iir_Predefined_Std_Ulogic_Match_Greater_Equal =>
+ return Synth_Compare (Id_Uge, Logic_Type);
+
+ when Iir_Predefined_Array_Equality
+ | Iir_Predefined_Record_Equality =>
+ if not Is_Matching_Bounds (Left.Typ, Right.Typ) then
+ Warning_Msg_Synth
+ (+Expr,
+ "length of '=' operands doesn't match, result is false");
+ return Create_Value_Discrete (0, Boolean_Type);
+ end if;
+ return Synth_Compare (Id_Eq, Boolean_Type);
+ when Iir_Predefined_Std_Ulogic_Array_Match_Equality =>
+ declare
+ Cst, Oper : Valtyp;
+ Res : Net;
+ begin
+ if Left.Typ.W /= Right.Typ.W then
+ Error_Msg_Synth
+ (+Expr, "operands of ?= don't have the same size");
+ return Create_Value_Discrete (0, Bit_Type);
+ end if;
+
+ if Is_Static (Left.Val) then
+ Cst := Left;
+ Oper := Right;
+ elsif Is_Static (Right.Val) then
+ Cst := Right;
+ Oper := Left;
+ else
+ Warning_Msg_Synth
+ (+Expr, "no operand of ?= is constant, handled like =");
+ return Synth_Compare (Id_Eq, Logic_Type);
+ end if;
+ Res := Synth_Match (Ctxt, Cst, Oper, Expr);
+ if Res = No_Net then
+ return Create_Value_Discrete (Std_Logic_X_Pos, Expr_Typ);
+ else
+ return Create_Value_Net (Res, Logic_Type);
+ end if;
+ end;
+ when Iir_Predefined_Std_Ulogic_Array_Match_Inequality =>
+ declare
+ Cst, Oper : Valtyp;
+ Res : Net;
+ begin
+ if Left.Typ.W /= Right.Typ.W then
+ Error_Msg_Synth
+ (+Expr, "operands of ?/= don't have the same size");
+ return Create_Value_Discrete (1, Bit_Type);
+ end if;
+
+ if Is_Static (Left.Val) then
+ Cst := Left;
+ Oper := Right;
+ elsif Is_Static (Right.Val) then
+ Cst := Right;
+ Oper := Left;
+ else
+ Warning_Msg_Synth
+ (+Expr, "no operand of ?/= is constant, handled like /=");
+ return Synth_Compare (Id_Ne, Logic_Type);
+ end if;
+ Res := Synth_Match (Ctxt, Cst, Oper, Expr, Id_Ne);
+ if Res = No_Net then
+ return Create_Value_Discrete (Std_Logic_X_Pos, Expr_Typ);
+ else
+ return Create_Value_Net (Res, Logic_Type);
+ end if;
+ end;
+ when Iir_Predefined_Array_Inequality
+ | Iir_Predefined_Record_Inequality =>
+ if not Is_Matching_Bounds (Left.Typ, Right.Typ) then
+ Warning_Msg_Synth
+ (+Expr,
+ "length of '/=' operands doesn't match, result is true");
+ return Create_Value_Discrete (1, Boolean_Type);
+ end if;
+ return Synth_Compare (Id_Ne, Boolean_Type);
+ when Iir_Predefined_Array_Greater =>
+ return Synth_Compare_Array (Id_Ugt, Boolean_Type);
+ when Iir_Predefined_Array_Greater_Equal =>
+ return Synth_Compare_Array (Id_Uge, Boolean_Type);
+ when Iir_Predefined_Array_Less =>
+ return Synth_Compare_Array (Id_Ult, Boolean_Type);
+
+ when Iir_Predefined_Array_Element_Concat =>
+ declare
+ L : constant Net := Get_Net (Ctxt, Left);
+ Bnd : Bound_Type;
+ N : Net;
+ begin
+ N := Build_Concat2 (Ctxt, L, Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ Bnd := Create_Bounds_From_Length
+ (Syn_Inst,
+ 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));
+ end;
+ when Iir_Predefined_Element_Array_Concat =>
+ declare
+ R : constant Net := Get_Net (Ctxt, Right);
+ Bnd : Bound_Type;
+ N : Net;
+ begin
+ N := Build_Concat2 (Ctxt, Get_Net (Ctxt, Left), R);
+ Set_Location (N, Expr);
+ Bnd := Create_Bounds_From_Length
+ (Syn_Inst,
+ 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));
+ end;
+ when Iir_Predefined_Element_Element_Concat =>
+ declare
+ N : Net;
+ Bnd : Bound_Type;
+ begin
+ N := Build_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));
+ end;
+ when Iir_Predefined_Array_Array_Concat =>
+ declare
+ L : constant Net := Get_Net (Ctxt, Left);
+ R : constant Net := Get_Net (Ctxt, Right);
+ Bnd : Bound_Type;
+ N : Net;
+ begin
+ N := Build_Concat2 (Ctxt, L, R);
+ Set_Location (N, Expr);
+ Bnd := Create_Bounds_From_Length
+ (Syn_Inst,
+ Get_Index_Type (Get_Type (Expr), 0),
+ 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));
+ end;
+ when Iir_Predefined_Integer_Plus =>
+ return Synth_Int_Dyadic (Id_Add);
+ when Iir_Predefined_Integer_Minus =>
+ return Synth_Int_Dyadic (Id_Sub);
+ when Iir_Predefined_Integer_Mul =>
+ return Synth_Int_Dyadic (Id_Smul);
+ when Iir_Predefined_Integer_Div =>
+ return Synth_Int_Dyadic (Id_Sdiv);
+ when Iir_Predefined_Integer_Mod =>
+ if Is_Static_Val (Right.Val) then
+ -- Optimize when the divisor is a power of 2.
+ declare
+ use Mutils;
+ Etype : constant Type_Acc :=
+ Get_Subtype_Object (Syn_Inst, Expr_Type);
+ R : constant Int64 := Get_Static_Discrete (Right);
+ Log_R : Natural;
+ N : Net;
+ begin
+ if R > 0 and then Is_Power2 (Uns64 (R)) then
+ Log_R := Clog2 (Uns64 (R));
+ pragma Assert (Log_R <= Natural (Left.Typ.W));
+ N := Get_Net (Ctxt, Left);
+ N := Build2_Extract (Ctxt, N, 0, Width (Log_R));
+ N := Build2_Uresize (Ctxt, N, Left.Typ.W,
+ Get_Location (Expr));
+ return Create_Value_Net (N, Etype);
+ end if;
+ end;
+ end if;
+ return Synth_Int_Dyadic (Id_Smod);
+ when Iir_Predefined_Integer_Rem =>
+ return Synth_Int_Dyadic (Id_Srem);
+ when Iir_Predefined_Integer_Exp =>
+ Error_Msg_Synth
+ (+Expr, "non-constant exponentiation not supported");
+ return No_Valtyp;
+ when Iir_Predefined_Integer_Less_Equal =>
+ return Synth_Compare (Id_Sle, Boolean_Type);
+ when Iir_Predefined_Integer_Less =>
+ return Synth_Compare (Id_Slt, Boolean_Type);
+ when Iir_Predefined_Integer_Greater_Equal =>
+ return Synth_Compare (Id_Sge, Boolean_Type);
+ when Iir_Predefined_Integer_Greater =>
+ return Synth_Compare (Id_Sgt, Boolean_Type);
+ when Iir_Predefined_Integer_Equality =>
+ return Synth_Compare (Id_Eq, Boolean_Type);
+ when Iir_Predefined_Integer_Inequality =>
+ return Synth_Compare (Id_Ne, Boolean_Type);
+ when Iir_Predefined_Integer_Minimum =>
+ return Synth_Minmax (Id_Slt);
+ when Iir_Predefined_Integer_Maximum =>
+ return Synth_Minmax (Id_Sgt);
+ when Iir_Predefined_Physical_Physical_Div =>
+ Error_Msg_Synth (+Expr, "non-constant division not supported");
+ return No_Valtyp;
+
+ when Iir_Predefined_Floating_Div =>
+ Error_Msg_Synth (+Expr, "non-constant division not supported");
+ return No_Valtyp;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Log
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Add_Slv_Log
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Add_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Log_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Log_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Log_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Log_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Log_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Log_Sgn_Slv =>
+ -- "+" (Unsigned, Unsigned)
+ return Synth_Dyadic_Uns_Uns (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Int_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Int_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Int =>
+ -- "+" (Unsigned, Natural)
+ return Synth_Dyadic_Uns_Nat (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Int_Slv =>
+ -- "+" (Natural, Unsigned)
+ return Synth_Dyadic_Nat_Uns (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Add_Slv_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Int_Slv =>
+ -- "+" (Signed, Integer)
+ return Synth_Dyadic_Sgn_Int (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Add_Int_Slv =>
+ -- "+" (Integer, Signed)
+ return Synth_Dyadic_Int_Sgn (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Sgn_Sgn
+ | 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_Sgn (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Sgn_Slv =>
+ -- "+" (Unsigned, Signed)
+ return Synth_Dyadic_Uns_Sgn_Sgn (Ctxt, Id_Add, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Uns_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Uns_Slv =>
+ -- "+" (Signed, Unsigned)
+ return Synth_Dyadic_Sgn_Uns_Sgn (Ctxt, Id_Add, Left, Right, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn
+ | 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
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Log
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Log_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Log_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Log_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Log_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Log_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Log_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Log_Sgn_Slv =>
+ -- "-" (Unsigned, Unsigned)
+ return Synth_Dyadic_Uns_Uns (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Slv =>
+ -- "-" (Signed, Signed)
+ return Synth_Dyadic_Sgn_Sgn (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Int_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Int_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Int =>
+ -- "-" (Unsigned, Natural)
+ return Synth_Dyadic_Uns_Nat (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Int_Slv =>
+ -- "-" (Natural, Unsigned)
+ return Synth_Dyadic_Nat_Uns (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Int_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Int =>
+ -- "-" (Signed, Integer)
+ return Synth_Dyadic_Sgn_Int (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Int_Slv =>
+ -- "-" (Integer, Signed)
+ return Synth_Dyadic_Int_Sgn (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Sgn_Slv =>
+ -- "-" (Unsigned, Signed)
+ return Synth_Dyadic_Uns_Sgn_Sgn (Ctxt, Id_Sub, Left, Right, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Uns_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Sgn_Uns_Slv =>
+ -- "-" (Signed, Unsigned)
+ return Synth_Dyadic_Sgn_Uns_Sgn (Ctxt, Id_Sub, Left, Right, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Mul_Slv_Slv =>
+ -- "*" (Signed, Signed)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, Left.Typ.W + Right.Typ.W,
+ Left, Right, True, True, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Int =>
+ -- "*" (Signed, Integer)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, 2 * Left.Typ.W,
+ Left, Right, True, True, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Int_Sgn =>
+ -- "*" (Integer, Signed)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, 2 * Right.Typ.W,
+ Left, Right, True, True, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Uns_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Uns_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Mul_Slv_Slv =>
+ -- "*" (unsigned, unsigned)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, Left.Typ.W + Right.Typ.W,
+ Left, Right, False, False, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Nat =>
+ -- "*" (unsigned, natural)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, 2 * Left.Typ.W,
+ Left, Right, False, False, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mul_Nat_Uns =>
+ -- "*" (natural, unsigned)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, 2 * Right.Typ.W,
+ Left, Right, False, False, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Uns_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Uns_Sgn_Slv =>
+ -- "*" (unsigned, signed)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, Left.Typ.W + 1 + Right.Typ.W,
+ Left, Right, False, True, Expr);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Uns_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Mul_Sgn_Uns_Slv =>
+ -- "*" (signed, unsigned)
+ return Synth_Dyadic_Xxx_Xxx
+ (Ctxt, Id_Smul, Left.Typ.W + Right.Typ.W + 1,
+ Left, Right, True, False, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Nat =>
+ return Synth_Udivmod (Id_Udiv, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Nat_Uns =>
+ return Synth_Udivmod (Id_Udiv, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Sgn =>
+ return Synth_Sdivmod (Id_Sdiv, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Int_Sgn =>
+ return Synth_Sdivmod (Id_Sdiv, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Uns_Nat =>
+ return Synth_Udivmod (Id_Umod, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Rem_Nat_Uns =>
+ return Synth_Udivmod (Id_Umod, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Sgn_Int =>
+ return Synth_Sdivmod (Id_Srem, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Rem_Int_Sgn =>
+ return Synth_Sdivmod (Id_Srem, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Uns_Nat =>
+ return Synth_Udivmod (Id_Umod, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Mod_Nat_Uns =>
+ return Synth_Udivmod (Id_Umod, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Sgn_Int =>
+ return Synth_Sdivmod (Id_Smod, Oper_Left);
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Mod_Int_Sgn =>
+ return Synth_Sdivmod (Id_Smod, Oper_Right);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Eq_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Uns_Uns =>
+ -- "=" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Eq_Slv_Int =>
+ -- "=" (Unsigned, Natural)
+ return Synth_Compare_Uns_Nat (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Eq_Int_Slv =>
+ -- "=" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Eq_Slv_Int =>
+ -- "=" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Eq_Slv_Slv =>
+ -- "=" (Signed, Signed) [resize]
+ return Synth_Compare_Sgn_Sgn (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Eq_Int_Slv =>
+ -- "=" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Int_Uns =>
+ -- "=" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Uns_Int =>
+ -- "=" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Uns_Sgn =>
+ -- "=" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Eq, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Eq_Sgn_Uns =>
+ -- "=" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Eq, Expr_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ne_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Uns_Uns =>
+ -- "/=" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Uns_Nat =>
+ -- "/=" (Unsigned, Natural)
+ return Synth_Compare_Uns_Nat (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ne_Int_Slv =>
+ -- "/=" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ne_Slv_Slv =>
+ -- "/=" (Signed, Signed) [resize]
+ return Synth_Compare_Sgn_Sgn (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ne_Slv_Int =>
+ -- "/=" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ne_Int_Slv =>
+ -- "/=" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Int_Uns =>
+ -- "/=" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Uns_Int
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ne_Slv_Int =>
+ -- "/=" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Uns_Sgn =>
+ -- "/=" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Ne, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ne_Sgn_Uns =>
+ -- "/=" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Ne, Expr_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Lt_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Uns_Uns =>
+ -- "<" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Ult, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Lt_Slv_Int =>
+ -- "<" (Unsigned, Natural)
+ if Is_Static (Right.Val) and then Read_Discrete (Right) = 0 then
+ -- Always false.
+ return Create_Value_Discrete (0, Expr_Typ);
+ end if;
+ return Synth_Compare_Uns_Nat (Id_Ult, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Lt_Int_Slv =>
+ -- "<" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Ult, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Lt_Slv_Slv =>
+ -- "<" (Signed, Signed) [resize]
+ return Synth_Compare_Sgn_Sgn (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Lt_Slv_Int =>
+ -- "<" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Lt_Int_Slv =>
+ -- "<" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Int_Uns =>
+ -- "<" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Uns_Int =>
+ -- "<" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Uns_Sgn =>
+ -- "<" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Slt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Lt_Sgn_Uns =>
+ -- "<" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Slt, Expr_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Le_Slv_Slv
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Le_Uns_Uns =>
+ -- "<=" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Ule, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Le_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Le_Slv_Slv =>
+ -- "<=" (Signed, Signed)
+ return Synth_Compare_Sgn_Sgn (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Le_Slv_Int =>
+ -- "<=" (Unsigned, Natural)
+ return Synth_Compare_Uns_Nat (Id_Ule, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Le_Int_Slv =>
+ -- "<=" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Ule, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Le_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Le_Slv_Int =>
+ -- "<=" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Le_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Le_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Le_Int_Slv =>
+ -- "<=" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Le_Int_Uns =>
+ -- "<=" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Le_Uns_Int =>
+ -- "<=" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Le_Uns_Sgn =>
+ -- "<=" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Sle, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Le_Sgn_Uns =>
+ -- "<=" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Sle, Expr_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Gt_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Uns_Uns =>
+ -- ">" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Ugt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Gt_Slv_Int =>
+ -- ">" (Unsigned, Natural)
+ return Synth_Compare_Uns_Nat (Id_Ugt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Gt_Int_Slv =>
+ -- ">" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Ugt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Gt_Slv_Slv =>
+ -- ">" (Signed, Signed) [resize]
+ return Synth_Compare_Sgn_Sgn (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Gt_Slv_Int =>
+ -- ">" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Gt_Int_Slv =>
+ -- ">" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Int_Uns =>
+ -- ">" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Uns_Int =>
+ -- ">" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Uns_Sgn =>
+ -- ">" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Sgt, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Gt_Sgn_Uns =>
+ -- ">" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Sgt, Expr_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ge_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Uns_Uns =>
+ -- ">=" (Unsigned, Unsigned) [resize]
+ return Synth_Compare_Uns_Uns (Id_Uge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Nat_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ge_Int_Slv =>
+ -- ">=" (Natural, Unsigned) [resize]
+ return Synth_Compare_Nat_Uns (Id_Uge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Ge_Slv_Int =>
+ -- ">=" (Unsigned, Natural)
+ return Synth_Compare_Uns_Nat (Id_Uge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ge_Slv_Slv =>
+ -- ">=" (Signed, Signed) [resize]
+ return Synth_Compare_Sgn_Sgn (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ge_Slv_Int =>
+ -- ">=" (Signed, Integer)
+ return Synth_Compare_Sgn_Int (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Int_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Int_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Ge_Int_Slv =>
+ -- ">=" (Integer, Signed)
+ return Synth_Compare_Int_Sgn (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Int_Uns =>
+ -- ">=" (Integer, Unsigned)
+ return Synth_Compare_Int_Uns (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Uns_Int =>
+ -- ">=" (Unsigned, Integer)
+ return Synth_Compare_Uns_Int (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Uns_Sgn =>
+ -- ">=" (Unsigned, Signed)
+ return Synth_Compare_Uns_Sgn (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Ge_Sgn_Uns =>
+ -- ">=" (Signed, Unsigned)
+ return Synth_Compare_Sgn_Uns (Id_Sge, Expr_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Sra_Sgn_Int =>
+ return Synth_Shift (Id_Asr, Id_Lsl);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Sll_Uns_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Sll_Sgn_Int
+ | Iir_Predefined_Ieee_1164_Vector_Sll =>
+ return Synth_Shift (Id_Lsl, Id_Lsr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Srl_Uns_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Srl_Sgn_Int
+ | Iir_Predefined_Ieee_1164_Vector_Srl =>
+ return Synth_Shift (Id_Lsr, Id_Lsl);
+
+ when Iir_Predefined_Ieee_1164_Vector_Ror =>
+ return Synth_Rotation (Id_Ror);
+
+ when others =>
+ Error_Msg_Synth (+Expr, "synth_dyadic_operation: unhandled "
+ & Iir_Predefined_Functions'Image (Def));
+ return No_Valtyp;
+ end case;
+ end Synth_Dyadic_Operation;
+
+ function Synth_Monadic_Operation (Syn_Inst : Synth_Instance_Acc;
+ Imp : Node;
+ Operand_Expr : Node;
+ Loc : Node) return Valtyp
+ is
+ Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
+ 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);
+ Operand : Valtyp;
+
+ function Synth_Bit_Monadic (Id : Monadic_Module_Id) return Valtyp
+ is
+ N : Net;
+ begin
+ N := Build_Monadic (Ctxt, Id, Get_Net (Ctxt, Operand));
+ Set_Location (N, Loc);
+ return Create_Value_Net (N, Operand.Typ);
+ end Synth_Bit_Monadic;
+
+ function Synth_Vec_Monadic (Id : Monadic_Module_Id) return Valtyp
+ is
+ Op: constant Net := Get_Net (Ctxt, Operand);
+ N : Net;
+ begin
+ N := Build_Monadic (Ctxt, Id, Op);
+ Set_Location (N, Loc);
+ return Create_Value_Net (N, Create_Res_Bound (Operand));
+ end Synth_Vec_Monadic;
+
+ function Synth_Vec_Reduce_Monadic
+ (Id : Reduce_Module_Id; Neg : Boolean := False) return Valtyp
+ is
+ Op: constant Net := Get_Net (Ctxt, Operand);
+ N : Net;
+ begin
+ N := Build_Reduce (Ctxt, Id, Op);
+ Set_Location (N, Loc);
+ if Neg then
+ N := Build_Monadic (Ctxt, Id_Not, N);
+ Set_Location (N, Loc);
+ end if;
+ return Create_Value_Net (N, Operand.Typ.Vec_El);
+ end Synth_Vec_Reduce_Monadic;
+ begin
+ Operand := Synth_Expression_With_Type (Syn_Inst, Operand_Expr, Oper_Typ);
+ if Operand = No_Valtyp then
+ return No_Valtyp;
+ end if;
+ Operand := Synth_Subtype_Conversion
+ (Ctxt, Operand, Oper_Typ, False, Loc);
+ 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));
+ end if;
+
+ case Def is
+ when Iir_Predefined_Error =>
+ return No_Valtyp;
+ when Iir_Predefined_Ieee_1164_Scalar_Not =>
+ return Synth_Bit_Monadic (Id_Not);
+ when Iir_Predefined_Boolean_Not
+ | Iir_Predefined_Bit_Not =>
+ 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 =>
+ return Synth_Vec_Monadic (Id_Not);
+ when Iir_Predefined_Ieee_Numeric_Std_Neg_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Neg_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Neg_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Neg_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Neg_Slv =>
+ return Synth_Vec_Monadic (Id_Neg);
+ when Iir_Predefined_Ieee_Numeric_Std_Abs_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Abs_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Abs_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Abs_Slv =>
+ return Synth_Vec_Monadic (Id_Abs);
+
+ when Iir_Predefined_Ieee_1164_And_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_And_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_And_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_And);
+ when Iir_Predefined_Ieee_1164_Nand_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_And, True);
+ when Iir_Predefined_Ieee_1164_Or_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Or);
+ when Iir_Predefined_Ieee_1164_Nor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Or, True);
+ when Iir_Predefined_Ieee_1164_Xor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Xor);
+ when Iir_Predefined_Ieee_1164_Xnor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns =>
+ return Synth_Vec_Reduce_Monadic (Id_Red_Xor, True);
+
+ when Iir_Predefined_Ieee_Std_Logic_Arith_Id_Uns_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Id_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Id_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Id_Sgn_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Id_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Id_Slv =>
+ -- Unary "+": nop
+ return Create_Value_Net (Get_Net (Ctxt, Operand),
+ Create_Res_Bound (Operand));
+
+ when Iir_Predefined_Ieee_1164_Condition_Operator =>
+ return Create_Value_Net
+ (Get_Net (Ctxt, Operand),
+ Get_Subtype_Object (Syn_Inst, Get_Type (Imp)));
+ when Iir_Predefined_Integer_Negation =>
+ declare
+ N : Net;
+ begin
+ N := Build_Monadic (Ctxt, Id_Neg, Get_Net (Ctxt, Operand));
+ Set_Location (N, Loc);
+ return Create_Value_Net (N, Operand.Typ);
+ end;
+
+ when others =>
+ Error_Msg_Synth
+ (+Loc,
+ "unhandled monadic: " & Iir_Predefined_Functions'Image (Def));
+ return No_Valtyp;
+ end case;
+ end Synth_Monadic_Operation;
+
+ function Synth_Shift_Rotate (Ctxt : Context_Acc;
+ Id : Shift_Rotate_Module_Id;
+ Left, Right : Valtyp;
+ Expr : Node) return Valtyp
+ is
+ L : constant Net := Get_Net (Ctxt, Left);
+ N : Net;
+ begin
+ N := Build_Shift_Rotate (Ctxt, Id, L, Get_Net (Ctxt, Right));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Create_Res_Bound (Left));
+ end Synth_Shift_Rotate;
+
+ function Synth_Find_Bit (Ctxt : Context_Acc;
+ Left, Right : Valtyp;
+ Res_Typ : Type_Acc;
+ Leftmost : Boolean;
+ Expr : Node) return Valtyp
+ is
+ pragma Assert (Left.Typ.Kind = Type_Vector);
+ Len : constant Uns32 := Left.Typ.Vbound.Len;
+ Max : Int32;
+ Rng : Discrete_Range_Type;
+ W : Uns32;
+ Typ : Type_Acc;
+ R_Net : Net;
+ L_Net : Net;
+ Res : Net;
+ begin
+ if Len = 0 then
+ return Create_Value_Int (-1, Res_Typ);
+ end if;
+
+ -- The intermediate result is computed using the least number of bits,
+ -- which must represent all positive values in the bounds using a
+ -- signed word (so that -1 is also represented).
+ Max := Int32'Max (Left.Typ.Vbound.Left, Left.Typ.Vbound.Right);
+ W := Netlists.Utils.Clog2 (Uns32 (Max)) + 1;
+ Rng := (Dir => Dir_To,
+ Is_Signed => True,
+ Left => -1,
+ Right => Int64 (Max));
+ Typ := Create_Discrete_Type (Rng, Res_Typ.Sz, W);
+
+ R_Net := Get_Net (Ctxt, Right);
+ L_Net := Get_Net (Ctxt, Left);
+ Res := Build2_Const_Int (Ctxt, -1, W);
+ for I in 0 .. Len - 1 loop
+ declare
+ Pos : Uns32;
+ V : Int64;
+ Sel : Net;
+ begin
+ if Leftmost then
+ -- Iterate from the right to the left.
+ Pos := I;
+ if Left.Typ.Vbound.Dir = Dir_To then
+ V := Int64 (Left.Typ.Vbound.Right) - Int64 (I);
+ else
+ V := Int64 (Left.Typ.Vbound.Right) + Int64 (I);
+ end if;
+ else
+ Pos := Len - I - 1;
+ if Left.Typ.Vbound.Dir = Dir_To then
+ V := Int64 (Left.Typ.Vbound.Left) + Int64 (I);
+ else
+ V := Int64 (Left.Typ.Vbound.Left) - Int64 (I);
+ end if;
+ end if;
+ Sel := Build2_Compare (Ctxt, Id_Eq,
+ Build2_Extract (Ctxt, L_Net, Pos, 1),
+ R_Net);
+ Set_Location (Sel, Expr);
+ Res := Build_Mux2 (Ctxt, Sel, Res, Build2_Const_Int (Ctxt, V, W));
+ Set_Location (Res, Expr);
+ end;
+ end loop;
+
+ return Synth_Subtype_Conversion (Ctxt, Create_Value_Net (Res, Typ),
+ Res_Typ, False, Expr);
+ end Synth_Find_Bit;
+
+ function Synth_Dynamic_Predefined_Function_Call
+ (Subprg_Inst : Synth_Instance_Acc; Expr : Node) return Valtyp
+ is
+ Ctxt : constant Context_Acc := Get_Build (Subprg_Inst);
+ Imp : constant Node := Get_Implementation (Expr);
+ Def : constant Iir_Predefined_Functions :=
+ Get_Implicit_Definition (Imp);
+ Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp);
+ Param1 : Node;
+ Param2 : Node;
+ Res_Typ : constant Type_Acc :=
+ Get_Subtype_Object (Subprg_Inst, Get_Type (Imp));
+
+ -- Resize PARAM1 to PARAM2 bit according to IS_SIGNED.
+ function Synth_Conv_Vector (Is_Signed : Boolean) return Valtyp
+ 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);
+ if not Is_Static (Size_Vt.Val) then
+ Error_Msg_Synth (+Expr, "size parameter must be constant");
+ 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));
+ end Synth_Conv_Vector;
+
+ L : Valtyp;
+ R : Valtyp;
+ 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 := No_Valtyp;
+ end if;
+ else
+ L := No_Valtyp;
+ R := No_Valtyp;
+ Param2 := Null_Node;
+ end if;
+
+ case Def is
+ when Iir_Predefined_Ieee_1164_Rising_Edge =>
+ declare
+ Edge : Net;
+ begin
+ Edge := Build_Posedge (Ctxt, Get_Net (Ctxt, L));
+ Set_Location (Edge, Expr);
+ return Create_Value_Net (Edge, Res_Typ);
+ end;
+ when Iir_Predefined_Ieee_1164_Falling_Edge =>
+ declare
+ Edge : Net;
+ begin
+ Edge := Build_Negedge (Ctxt, Get_Net (Ctxt, L));
+ Set_Location (Edge, Expr);
+ return Create_Value_Net (Edge, Res_Typ);
+ end;
+ when Iir_Predefined_Ieee_1164_Scalar_Is_X
+ | Iir_Predefined_Ieee_1164_Vector_Is_X =>
+ -- Always false.
+ return Create_Value_Discrete (0, Boolean_Type);
+ when Iir_Predefined_Ieee_1164_To_Bitvector
+ | Iir_Predefined_Ieee_1164_To_Stdlogicvector_Suv
+ | Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv
+ | Iir_Predefined_Ieee_1164_To_Stdulogicvector_Bv
+ | Iir_Predefined_Ieee_Numeric_Std_To_01_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_To_01_Sgn
+ | Iir_Predefined_Ieee_1164_To_X01_Slv =>
+ if Is_Static (L.Val) then
+ raise Internal_Error;
+ end if;
+ -- A no-op (with change of bounds).
+ return Create_Value_Net (Get_Net (Ctxt, L), Create_Res_Bound (L));
+ when Iir_Predefined_Ieee_1164_To_Bit
+ | Iir_Predefined_Ieee_1164_To_X01_Log
+ | Iir_Predefined_Ieee_1164_To_Stdulogic =>
+ -- A no-op.
+ return Create_Value_Net (Get_Net (Ctxt, L), Res_Typ);
+
+ 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_Tosgn_Int_Nat_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Int =>
+ return Synth_Conv_Vector (True);
+ when Iir_Predefined_Ieee_Numeric_Std_Toint_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Integer_Slv_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Integer_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Integer_Log
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Conv_Integer =>
+ -- UNSIGNED to Natural.
+ return Create_Value_Net
+ (Synth_Uresize (Ctxt, L, Res_Typ.W, Expr), Res_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Toint_Sgn_Int
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Integer_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Conv_Integer =>
+ -- SIGNED to Integer.
+ return Create_Value_Net
+ (Synth_Sresize (Ctxt, L, Res_Typ.W, Expr), Res_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Log
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Ext =>
+ 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
+ (Synth_Uresize (Ctxt, L, W, Expr),
+ Create_Vec_Type_By_Length (W, Logic_Type));
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat
+ | 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;
+ when Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Sgn_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Shl_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Shl_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Shl
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Shl =>
+ return Synth_Shift_Rotate (Ctxt, Id_Lsl, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Shr_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Shr =>
+ return Synth_Shift_Rotate (Ctxt, Id_Lsr, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Sgn_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Shr_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Signed_Shr =>
+ return Synth_Shift_Rotate (Ctxt, Id_Asr, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Uns_Nat =>
+ return Synth_Shift_Rotate (Ctxt, Id_Rol, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Uns_Nat =>
+ return Synth_Shift_Rotate (Ctxt, Id_Ror, L, R, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Uns =>
+ return Synth_Dyadic_Uns_Uns (Ctxt, Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Nat =>
+ return Synth_Dyadic_Uns_Nat (Ctxt, Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Nat_Uns =>
+ return Synth_Dyadic_Nat_Uns (Ctxt, Id_Umin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Sgn =>
+ return Synth_Dyadic_Sgn_Sgn (Ctxt, Id_Smin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Int =>
+ return Synth_Dyadic_Sgn_Int (Ctxt, Id_Smin, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Int_Sgn =>
+ return Synth_Dyadic_Int_Sgn (Ctxt, Id_Smin, L, R, Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Uns =>
+ return Synth_Dyadic_Uns_Uns (Ctxt, Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Nat =>
+ return Synth_Dyadic_Uns_Nat (Ctxt, Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Nat_Uns =>
+ return Synth_Dyadic_Nat_Uns (Ctxt, Id_Umax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Sgn =>
+ return Synth_Dyadic_Sgn_Sgn (Ctxt, Id_Smax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Int =>
+ return Synth_Dyadic_Sgn_Int (Ctxt, Id_Smax, L, R, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Int_Sgn =>
+ return Synth_Dyadic_Int_Sgn (Ctxt, Id_Smax, L, R, Expr);
+
+ when Iir_Predefined_Ieee_Std_Logic_Misc_Or_Reduce_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Misc_Or_Reduce_Suv =>
+ declare
+ N : Net;
+ begin
+ N := Build_Reduce (Ctxt, Id_Red_Or, Get_Net (Ctxt, L));
+ Set_Location (N, Expr);
+ return Create_Value_Net (N, Res_Typ);
+ end;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Slv =>
+ declare
+ Cst, Oper : Valtyp;
+ Res : Net;
+ begin
+ if Is_Static (L.Val) then
+ Cst := L;
+ Oper := R;
+ elsif Is_Static (R.Val) then
+ Cst := R;
+ Oper := L;
+ else
+ Error_Msg_Synth
+ (+Expr, "one operand of std_match must be constant");
+ return No_Valtyp;
+ end if;
+ if Oper.Typ.W /= Cst.Typ.W then
+ Error_Msg_Synth
+ (+Expr, "operands of std_match don't have the same size");
+ return Create_Value_Discrete (0, Boolean_Type);
+ end if;
+ Strip_Const (Cst);
+ Res := Synth_Match (Ctxt, Cst, Oper, Expr);
+ if Res = No_Net then
+ return Create_Value_Discrete (0, Boolean_Type);
+ else
+ return Create_Value_Net (Res, Boolean_Type);
+ end if;
+ end;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Find_Leftmost_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Find_Leftmost_Uns =>
+ return Synth_Find_Bit (Ctxt, L, R, Res_Typ, True, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Find_Rightmost_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Find_Rightmost_Uns =>
+ return Synth_Find_Bit (Ctxt, L, R, Res_Typ, False, Expr);
+
+ when others =>
+ Error_Msg_Synth
+ (+Expr,
+ "unhandled function: " & Iir_Predefined_Functions'Image (Def));
+ return No_Valtyp;
+ end case;
+ end Synth_Dynamic_Predefined_Function_Call;
+
+ function Synth_Predefined_Function_Call
+ (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Valtyp
+ is
+ Imp : constant Node := Get_Implementation (Expr);
+ Assoc_Chain : constant Node := Get_Parameter_Association_Chain (Expr);
+ Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp);
+ Inter : Node;
+ Subprg_Inst : Synth_Instance_Acc;
+ M : Areapools.Mark_Type;
+ Static : Boolean;
+ Res : Valtyp;
+ Mt : Memtyp;
+ begin
+ Areapools.Mark (M, Instance_Pool.all);
+ Subprg_Inst := Make_Instance (Syn_Inst, Imp);
+
+ Synth_Subprogram_Association
+ (Subprg_Inst, Syn_Inst, Inter_Chain, Assoc_Chain);
+
+ if Is_Error (Subprg_Inst) then
+ Res := No_Valtyp;
+ else
+ -- If all operands are static, handle the call differently.
+ Static := True;
+ Inter := Inter_Chain;
+ while Inter /= Null_Node loop
+ if not Is_Static (Get_Value (Subprg_Inst, Inter).Val) then
+ Static := False;
+ exit;
+ end if;
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ if Static then
+ Mt := Synth_Static_Predefined_Function_Call (Subprg_Inst, Expr);
+ if Mt /= Null_Memtyp then
+ Res := Create_Value_Memtyp (Mt);
+ else
+ Res := No_Valtyp;
+ end if;
+ else
+ Res := Synth_Dynamic_Predefined_Function_Call (Subprg_Inst, Expr);
+ end if;
+ end if;
+
+ Free_Instance (Subprg_Inst);
+ Areapools.Release (M, Instance_Pool.all);
+
+ return Res;
+ end Synth_Predefined_Function_Call;
+
+ function Synth_Operator_Function_Call
+ (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Valtyp
+ is
+ Imp : constant Node := Get_Implementation (Expr);
+ Assoc : Node;
+ Inter : Node;
+ Op1, Op2 : Node;
+ begin
+ Assoc := Get_Parameter_Association_Chain (Expr);
+ Inter := Get_Interface_Declaration_Chain (Imp);
+
+ Op1 := Get_Actual (Assoc);
+ if Get_Chain (Inter) = Null_Node then
+ return Synth_Monadic_Operation (Syn_Inst, Imp, Op1, Expr);
+ else
+ Op2 := Get_Actual (Get_Chain (Assoc));
+ return Synth_Dyadic_Operation (Syn_Inst, Imp, Op1, Op2, Expr);
+ end if;
+ end Synth_Operator_Function_Call;
+end Synth.Vhdl_Oper;