aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-vhdl_eval.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-vhdl_eval.adb')
-rw-r--r--src/synth/synth-vhdl_eval.adb1737
1 files changed, 1578 insertions, 159 deletions
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb
index c6846718d..ab1304190 100644
--- a/src/synth/synth-vhdl_eval.adb
+++ b/src/synth/synth-vhdl_eval.adb
@@ -18,9 +18,14 @@
with Types; use Types;
with Types_Utils; use Types_Utils;
+with Name_Table;
with Grt.Types; use Grt.Types;
+with Grt.Vhdl_Types; use Grt.Vhdl_Types;
+with Grt.To_Strings;
+with Vhdl.Utils;
+with Vhdl.Evaluation;
with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164;
with Elab.Memtype; use Elab.Memtype;
@@ -47,20 +52,36 @@ package body Synth.Vhdl_Eval is
(False => (others => False),
True => (True => True, False => False));
+ Tf_2d_Nand : constant Tf_Table_2d :=
+ (False => (others => True),
+ True => (True => False, False => True));
+
+ Tf_2d_Or : constant Tf_Table_2d :=
+ (False => (True => True, False => False),
+ True => (True => True, False => True));
+
+ Tf_2d_Nor : constant Tf_Table_2d :=
+ (False => (True => False, False => True),
+ True => (True => False, False => False));
+
Tf_2d_Xor : constant Tf_Table_2d :=
(False => (False => False, True => True),
True => (False => True, True => False));
+ Tf_2d_Xnor : constant Tf_Table_2d :=
+ (False => (False => True, True => False),
+ True => (False => False, True => True));
+
function Create_Res_Bound (Prev : Type_Acc) return Type_Acc is
begin
- if Prev.Vbound.Dir = Dir_Downto
- and then Prev.Vbound.Right = 0
+ if Prev.Abound.Dir = Dir_Downto
+ and then Prev.Abound.Right = 0
then
-- Normalized range
return Prev;
end if;
- return Create_Vec_Type_By_Length (Prev.W, Prev.Vec_El);
+ return Create_Vec_Type_By_Length (Prev.W, Prev.Arr_El);
end Create_Res_Bound;
function Eval_Vector_Dyadic (Left, Right : Memtyp;
@@ -88,6 +109,62 @@ package body Synth.Vhdl_Eval is
return Res;
end Eval_Vector_Dyadic;
+ function Eval_Logic_Vector_Scalar (Vect, Scal : Memtyp;
+ Op : Table_2d) return Memtyp
+ is
+ Res : Memtyp;
+ Vs, Vv, Vr : Std_Ulogic;
+ begin
+ Res := Create_Memory (Create_Res_Bound (Vect.Typ));
+ Vs := Read_Std_Logic (Scal.Mem, 0);
+ for I in 1 .. Vect.Typ.Abound.Len loop
+ Vv := Read_Std_Logic (Vect.Mem, I - 1);
+ Vr := Op (Vs, Vv);
+ Write_Std_Logic (Res.Mem, I - 1, Vr);
+ end loop;
+ return Res;
+ end Eval_Logic_Vector_Scalar;
+
+ function Eval_Logic_Scalar (Left, Right : Memtyp;
+ Op : Table_2d;
+ Neg : Boolean := False) return Memtyp
+ is
+ Res : Std_Ulogic;
+ begin
+ Res := Op (Read_Std_Logic (Left.Mem, 0), Read_Std_Logic (Right.Mem, 0));
+ if Neg then
+ Res := Not_Table (Res);
+ end if;
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Left.Typ);
+ end Eval_Logic_Scalar;
+
+ function Eval_Vector_Match (Left, Right : Memtyp;
+ Neg : Boolean;
+ Loc : Syn_Src) return Memtyp
+ is
+ Res : Std_Ulogic;
+ begin
+ if Left.Typ.W /= Right.Typ.W then
+ Error_Msg_Synth (+Loc, "length of operands mismatch");
+ return Null_Memtyp;
+ end if;
+
+ Res := '1';
+ for I in 1 .. Left.Typ.Abound.Len loop
+ declare
+ Ls : constant Std_Ulogic := Read_Std_Logic (Left.Mem, I - 1);
+ Rs : constant Std_Ulogic := Read_Std_Logic (Right.Mem, I - 1);
+ begin
+ Res := And_Table (Res, Match_Eq_Table (Ls, Rs));
+ end;
+ end loop;
+
+ if Neg then
+ Res := Not_Table (Res);
+ end if;
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Left.Typ.Arr_El);
+ end Eval_Vector_Match;
+
function Eval_TF_Vector_Dyadic (Left, Right : Memtyp;
Op : Tf_Table_2d;
Loc : Syn_Src) return Memtyp
@@ -124,11 +201,189 @@ package body Synth.Vhdl_Eval is
return Res;
end Eval_TF_Array_Element;
- function Get_Static_Ulogic (Op : Memtyp) return Std_Ulogic is
+ function Compare (L, R : Memtyp) return Order_Type is
+ begin
+ case L.Typ.Kind is
+ when Type_Bit
+ | Type_Logic =>
+ declare
+ Lv : constant Ghdl_U8 := Read_U8 (L.Mem);
+ Rv : constant Ghdl_U8 := Read_U8 (R.Mem);
+ begin
+ if Lv < Rv then
+ return Less;
+ elsif Lv > Rv then
+ return Greater;
+ else
+ return Equal;
+ end if;
+ end;
+ when Type_Discrete =>
+ pragma Assert (L.Typ.Sz = R.Typ.Sz);
+ if L.Typ.Sz = 1 then
+ declare
+ Lv : constant Ghdl_U8 := Read_U8 (L.Mem);
+ Rv : constant Ghdl_U8 := Read_U8 (R.Mem);
+ begin
+ if Lv < Rv then
+ return Less;
+ elsif Lv > Rv then
+ return Greater;
+ else
+ return Equal;
+ end if;
+ end;
+ elsif L.Typ.Sz = 4 then
+ declare
+ Lv : constant Ghdl_I32 := Read_I32 (L.Mem);
+ Rv : constant Ghdl_I32 := Read_I32 (R.Mem);
+ begin
+ if Lv < Rv then
+ return Less;
+ elsif Lv > Rv then
+ return Greater;
+ else
+ return Equal;
+ end if;
+ end;
+ else
+ raise Internal_Error;
+ end if;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Compare;
+
+ function Compare_Array (L, R : Memtyp) return Order_Type
+ is
+ Len : Uns32;
+ Res : Order_Type;
+ begin
+ Len := Uns32'Min (L.Typ.Abound.Len, R.Typ.Abound.Len);
+ for I in 1 .. Size_Type (Len) loop
+ Res := Compare
+ ((L.Typ.Arr_El, L.Mem + (I - 1) * L.Typ.Arr_El.Sz),
+ (R.Typ.Arr_El, R.Mem + (I - 1) * R.Typ.Arr_El.Sz));
+ if Res /= Equal then
+ return Res;
+ end if;
+ end loop;
+ if L.Typ.Abound.Len > Len then
+ return Greater;
+ end if;
+ if R.Typ.Abound.Len > Len then
+ return Less;
+ end if;
+ return Equal;
+ end Compare_Array;
+
+ -- Execute shift and rot.
+ -- ZERO is the value to be used for '0' (for shifts).
+ function Execute_Shift_Operator (Left : Memtyp;
+ Count : Int64;
+ Zero : Ghdl_U8;
+ Op : Iir_Predefined_Shift_Functions)
+ return Memtyp
+ is
+ Cnt : Uns32;
+ Len : constant Uns32 := Left.Typ.Abound.Len;
+ Dir_Left : Boolean;
+ P : Size_Type;
+ Res : Memtyp;
+ E : Ghdl_U8;
begin
- pragma Assert (Op.Typ.Kind = Type_Logic);
- return Std_Ulogic'Val (Read_U8 (Op.Mem));
- end Get_Static_Ulogic;
+ -- LRM93 7.2.3
+ -- That is, if R is 0 or if L is a null array, the return value is L.
+ if Count = 0 or else Len = 0 then
+ return Left;
+ end if;
+
+ case Op is
+ when Iir_Predefined_Array_Sll
+ | Iir_Predefined_Array_Sla
+ | Iir_Predefined_Array_Rol =>
+ Dir_Left := True;
+ when Iir_Predefined_Array_Srl
+ | Iir_Predefined_Array_Sra
+ | Iir_Predefined_Array_Ror =>
+ Dir_Left := False;
+ end case;
+ if Count < 0 then
+ Cnt := Uns32 (-Count);
+ Dir_Left := not Dir_Left;
+ else
+ Cnt := Uns32 (Count);
+ end if;
+
+ case Op is
+ when Iir_Predefined_Array_Sll
+ | Iir_Predefined_Array_Srl =>
+ E := Zero;
+ when Iir_Predefined_Array_Sla
+ | Iir_Predefined_Array_Sra =>
+ if Dir_Left then
+ E := Read_U8 (Left.Mem + Size_Type (Len - 1));
+ else
+ E := Read_U8 (Left.Mem);
+ end if;
+ when Iir_Predefined_Array_Rol
+ | Iir_Predefined_Array_Ror =>
+ Cnt := Cnt mod Len;
+ if not Dir_Left then
+ Cnt := (Len - Cnt) mod Len;
+ end if;
+ end case;
+
+ Res := Create_Memory (Left.Typ);
+ P := 0;
+
+ case Op is
+ when Iir_Predefined_Array_Sll
+ | Iir_Predefined_Array_Srl
+ | Iir_Predefined_Array_Sla
+ | Iir_Predefined_Array_Sra =>
+ if Dir_Left then
+ if Cnt < Len then
+ for I in Cnt .. Len - 1 loop
+ Write_U8 (Res.Mem + P,
+ Read_U8 (Left.Mem + Size_Type (I)));
+ P := P + 1;
+ end loop;
+ else
+ Cnt := Len;
+ end if;
+ for I in 0 .. Cnt - 1 loop
+ Write_U8 (Res.Mem + P, E);
+ P := P + 1;
+ end loop;
+ else
+ if Cnt > Len then
+ Cnt := Len;
+ end if;
+ for I in 0 .. Cnt - 1 loop
+ Write_U8 (Res.Mem + P, E);
+ P := P + 1;
+ end loop;
+ for I in Cnt .. Len - 1 loop
+ Write_U8 (Res.Mem + P,
+ Read_U8 (Left.Mem + Size_Type (I - Cnt)));
+ P := P + 1;
+ end loop;
+ end if;
+ when Iir_Predefined_Array_Rol
+ | Iir_Predefined_Array_Ror =>
+ for I in 1 .. Len loop
+ Write_U8 (Res.Mem + P,
+ Read_U8 (Left.Mem + Size_Type (Cnt)));
+ P := P + 1;
+ Cnt := Cnt + 1;
+ if Cnt = Len then
+ Cnt := 0;
+ end if;
+ end loop;
+ end case;
+ return Res;
+ end Execute_Shift_Operator;
procedure Check_Integer_Overflow
(Val : in out Int64; Typ : Type_Acc; Loc : Syn_Src) is
@@ -234,17 +489,6 @@ package body Synth.Vhdl_Eval is
(Read_Discrete (Left) ** Natural (Read_Discrete (Right)),
Res_Typ);
- when Iir_Predefined_Physical_Minimum
- | Iir_Predefined_Integer_Minimum =>
- return Create_Memory_Discrete
- (Int64'Min (Read_Discrete (Left), Read_Discrete (Right)),
- Res_Typ);
- when Iir_Predefined_Physical_Maximum
- | Iir_Predefined_Integer_Maximum =>
- return Create_Memory_Discrete
- (Int64'Max (Read_Discrete (Left), Read_Discrete (Right)),
- Res_Typ);
-
when Iir_Predefined_Integer_Less_Equal
| Iir_Predefined_Physical_Less_Equal
| Iir_Predefined_Enum_Less_Equal =>
@@ -267,12 +511,14 @@ package body Synth.Vhdl_Eval is
(Read_Discrete (Left) > Read_Discrete (Right));
when Iir_Predefined_Integer_Equality
| Iir_Predefined_Physical_Equality
- | Iir_Predefined_Enum_Equality =>
+ | Iir_Predefined_Enum_Equality
+ | Iir_Predefined_Bit_Match_Equality =>
return Create_Memory_Boolean
(Read_Discrete (Left) = Read_Discrete (Right));
when Iir_Predefined_Integer_Inequality
| Iir_Predefined_Physical_Inequality
- | Iir_Predefined_Enum_Inequality =>
+ | Iir_Predefined_Enum_Inequality
+ | Iir_Predefined_Bit_Match_Inequality =>
return Create_Memory_Boolean
(Read_Discrete (Left) /= Read_Discrete (Right));
@@ -333,9 +579,9 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Array_Array_Concat =>
declare
L_Len : constant Iir_Index32 :=
- Iir_Index32 (Get_Bound_Length (Left.Typ, 1));
+ Iir_Index32 (Get_Bound_Length (Left.Typ));
R_Len : constant Iir_Index32 :=
- Iir_Index32 (Get_Bound_Length (Right.Typ, 1));
+ Iir_Index32 (Get_Bound_Length (Right.Typ));
Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ);
Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ);
Bnd : Bound_Type;
@@ -344,7 +590,7 @@ package body Synth.Vhdl_Eval is
begin
Check_Matching_Bounds (Le_Typ, Re_Typ, Expr);
Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length
- (Get_Uarray_First_Index (Res_Typ).Drange, L_Len + R_Len);
+ (Get_Uarray_Index (Res_Typ).Drange, L_Len + R_Len);
Res_St := Create_Onedimensional_Array_Subtype
(Res_Typ, Bnd, Le_Typ);
Res := Create_Memory (Res_St);
@@ -359,7 +605,7 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Element_Array_Concat =>
declare
Rlen : constant Iir_Index32 :=
- Get_Array_Flat_Length (Right.Typ);
+ Iir_Index32 (Get_Bound_Length (Right.Typ));
Re_Typ : constant Type_Acc := Get_Array_Element (Right.Typ);
Bnd : Bound_Type;
Res_St : Type_Acc;
@@ -367,7 +613,7 @@ package body Synth.Vhdl_Eval is
begin
Check_Matching_Bounds (Left.Typ, Re_Typ, Expr);
Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length
- (Get_Uarray_First_Index (Res_Typ).Drange, 1 + Rlen);
+ (Get_Uarray_Index (Res_Typ).Drange, 1 + Rlen);
Res_St := Create_Onedimensional_Array_Subtype
(Res_Typ, Bnd, Re_Typ);
Res := Create_Memory (Res_St);
@@ -378,7 +624,8 @@ package body Synth.Vhdl_Eval is
end;
when Iir_Predefined_Array_Element_Concat =>
declare
- Llen : constant Iir_Index32 := Get_Array_Flat_Length (Left.Typ);
+ Llen : constant Iir_Index32 :=
+ Iir_Index32 (Get_Bound_Length (Left.Typ));
Le_Typ : constant Type_Acc := Get_Array_Element (Left.Typ);
Bnd : Bound_Type;
Res_St : Type_Acc;
@@ -386,7 +633,7 @@ package body Synth.Vhdl_Eval is
begin
Check_Matching_Bounds (Le_Typ, Right.Typ, Expr);
Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length
- (Get_Uarray_First_Index (Res_Typ).Drange, Llen + 1);
+ (Get_Uarray_Index (Res_Typ).Drange, Llen + 1);
Res_St := Create_Onedimensional_Array_Subtype
(Res_Typ, Bnd, Le_Typ);
Res := Create_Memory (Res_St);
@@ -395,234 +642,646 @@ package body Synth.Vhdl_Eval is
Right.Mem, Right.Typ.Sz);
return Res;
end;
+ when Iir_Predefined_Element_Element_Concat =>
+ declare
+ El_Typ : constant Type_Acc := Left.Typ;
+ Bnd : Bound_Type;
+ Res_St : Type_Acc;
+ Res : Memtyp;
+ begin
+ Check_Matching_Bounds (Left.Typ, Right.Typ, Expr);
+ Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length
+ (Get_Uarray_Index (Res_Typ).Drange, 2);
+ Res_St := Create_Onedimensional_Array_Subtype
+ (Res_Typ, Bnd, El_Typ);
+ Res := Create_Memory (Res_St);
+ Copy_Memory (Res.Mem, Left.Mem, El_Typ.Sz);
+ Copy_Memory (Res.Mem + El_Typ.Sz,
+ Right.Mem, El_Typ.Sz);
+ return Res;
+ end;
when Iir_Predefined_Array_Equality
- | Iir_Predefined_Record_Equality =>
- return Create_Memory_U8
- (Boolean'Pos (Is_Equal (Left, Right)), Boolean_Type);
+ | Iir_Predefined_Record_Equality
+ | Iir_Predefined_Bit_Array_Match_Equality =>
+ return Create_Memory_Boolean (Is_Equal (Left, Right));
when Iir_Predefined_Array_Inequality
- | Iir_Predefined_Record_Inequality =>
- return Create_Memory_U8
- (Boolean'Pos (not Is_Equal (Left, Right)), Boolean_Type);
+ | Iir_Predefined_Record_Inequality
+ | Iir_Predefined_Bit_Array_Match_Inequality =>
+ return Create_Memory_Boolean (not Is_Equal (Left, Right));
when Iir_Predefined_Access_Equality =>
- return Create_Memory_U8
- (Boolean'Pos (Read_Access (Left) = Read_Access (Right)),
- Boolean_Type);
+ return Create_Memory_Boolean
+ (Read_Access (Left) = Read_Access (Right));
when Iir_Predefined_Access_Inequality =>
- return Create_Memory_U8
- (Boolean'Pos (Read_Access (Left) /= Read_Access (Right)),
- Boolean_Type);
+ return Create_Memory_Boolean
+ (Read_Access (Left) /= Read_Access (Right));
+ when Iir_Predefined_Array_Less =>
+ return Create_Memory_Boolean
+ (Compare_Array (Left, Right) = Less);
+ when Iir_Predefined_Array_Less_Equal =>
+ return Create_Memory_Boolean
+ (Compare_Array (Left, Right) <= Equal);
+ when Iir_Predefined_Array_Greater =>
+ return Create_Memory_Boolean
+ (Compare_Array (Left, Right) = Greater);
+ when Iir_Predefined_Array_Greater_Equal =>
+ return Create_Memory_Boolean
+ (Compare_Array (Left, Right) >= Equal);
+
+ when Iir_Predefined_Array_Maximum =>
+ -- IEEE 1076-2008 5.3.2.4 Predefined operations on array types
+ if Compare_Array (Left, Right) = Less then
+ return Right;
+ else
+ return Left;
+ end if;
+ when Iir_Predefined_Array_Minimum =>
+ -- IEEE 1076-2008 5.3.2.4 Predefined operations on array types
+ if Compare_Array (Left, Right) = Less then
+ return Left;
+ else
+ return Right;
+ end if;
+
+ when Iir_Predefined_Array_Sll
+ | Iir_Predefined_Array_Srl
+ | Iir_Predefined_Array_Rol
+ | Iir_Predefined_Array_Ror =>
+ return Execute_Shift_Operator
+ (Left, Read_Discrete (Right), 0, Def);
+
+ when Iir_Predefined_TF_Array_And =>
+ return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_And, Expr);
+ when Iir_Predefined_TF_Array_Or =>
+ return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Or, Expr);
when Iir_Predefined_TF_Array_Xor =>
return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Xor, Expr);
+ when Iir_Predefined_TF_Array_Nand =>
+ return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Nand, Expr);
+ when Iir_Predefined_TF_Array_Nor =>
+ return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Nor, Expr);
+ when Iir_Predefined_TF_Array_Xnor =>
+ return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Xnor, Expr);
+
+ when Iir_Predefined_TF_Element_Array_Or =>
+ return Eval_TF_Array_Element (Left, Right, Tf_2d_Or);
+ when Iir_Predefined_TF_Array_Element_Or =>
+ return Eval_TF_Array_Element (Right, Left, Tf_2d_Or);
+
+ when Iir_Predefined_TF_Element_Array_Nor =>
+ return Eval_TF_Array_Element (Left, Right, Tf_2d_Nor);
+ when Iir_Predefined_TF_Array_Element_Nor =>
+ return Eval_TF_Array_Element (Right, Left, Tf_2d_Nor);
when Iir_Predefined_TF_Element_Array_And =>
return Eval_TF_Array_Element (Left, Right, Tf_2d_And);
when Iir_Predefined_TF_Array_Element_And =>
return Eval_TF_Array_Element (Right, Left, Tf_2d_And);
+ when Iir_Predefined_TF_Element_Array_Nand =>
+ return Eval_TF_Array_Element (Left, Right, Tf_2d_Nand);
+ when Iir_Predefined_TF_Array_Element_Nand =>
+ return Eval_TF_Array_Element (Right, Left, Tf_2d_Nand);
+
+ when Iir_Predefined_TF_Element_Array_Xor =>
+ return Eval_TF_Array_Element (Left, Right, Tf_2d_Xor);
+ when Iir_Predefined_TF_Array_Element_Xor =>
+ return Eval_TF_Array_Element (Right, Left, Tf_2d_Xor);
+
+ when Iir_Predefined_TF_Element_Array_Xnor =>
+ return Eval_TF_Array_Element (Left, Right, Tf_2d_Xnor);
+ when Iir_Predefined_TF_Array_Element_Xnor =>
+ return Eval_TF_Array_Element (Right, Left, Tf_2d_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 Eval_Vector_Dyadic (Left, Right, And_Table, Expr);
+ when Iir_Predefined_Ieee_1164_Vector_Nand
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn_Sgn =>
+ return Eval_Vector_Dyadic (Left, Right, Nand_Table, Expr);
+
when Iir_Predefined_Ieee_1164_Vector_Or
| Iir_Predefined_Ieee_Numeric_Std_Or_Uns_Uns
| Iir_Predefined_Ieee_Numeric_Std_Or_Sgn_Sgn =>
return Eval_Vector_Dyadic (Left, Right, Or_Table, Expr);
+ when Iir_Predefined_Ieee_1164_Vector_Nor
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn_Sgn =>
+ return Eval_Vector_Dyadic (Left, Right, Nor_Table, Expr);
+
when Iir_Predefined_Ieee_1164_Vector_Xor
| Iir_Predefined_Ieee_Numeric_Std_Xor_Uns_Uns
| Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn_Sgn =>
return Eval_Vector_Dyadic (Left, Right, Xor_Table, Expr);
- when Iir_Predefined_Ieee_1164_Scalar_Or =>
- return Create_Memory_U8
- (Std_Ulogic'Pos (Or_Table (Get_Static_Ulogic (Left),
- Get_Static_Ulogic (Right))),
- Res_Typ);
+ when Iir_Predefined_Ieee_1164_Vector_Xnor
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn_Sgn =>
+ return Eval_Vector_Dyadic (Left, Right, Xnor_Table, Expr);
when Iir_Predefined_Ieee_1164_Scalar_And =>
- return Create_Memory_U8
- (Std_Ulogic'Pos (And_Table (Get_Static_Ulogic (Left),
- Get_Static_Ulogic (Right))),
- Res_Typ);
-
+ return Eval_Logic_Scalar (Left, Right, And_Table);
+ when Iir_Predefined_Ieee_1164_Scalar_Or =>
+ return Eval_Logic_Scalar (Left, Right, Or_Table);
when Iir_Predefined_Ieee_1164_Scalar_Xor =>
- return Create_Memory_U8
- (Std_Ulogic'Pos (Xor_Table (Get_Static_Ulogic (Left),
- Get_Static_Ulogic (Right))),
- Res_Typ);
+ return Eval_Logic_Scalar (Left, Right, Xor_Table);
+ when Iir_Predefined_Ieee_1164_Scalar_Nand =>
+ return Eval_Logic_Scalar (Left, Right, Nand_Table);
+ when Iir_Predefined_Ieee_1164_Scalar_Nor =>
+ return Eval_Logic_Scalar (Left, Right, Nor_Table);
+ when Iir_Predefined_Ieee_1164_Scalar_Xnor =>
+ return Eval_Logic_Scalar (Left, Right, Xnor_Table);
+
+ when Iir_Predefined_Std_Ulogic_Match_Equality =>
+ return Eval_Logic_Scalar (Left, Right, Match_Eq_Table);
+ when Iir_Predefined_Std_Ulogic_Match_Inequality =>
+ return Eval_Logic_Scalar (Left, Right, Match_Eq_Table, True);
+ when Iir_Predefined_Std_Ulogic_Match_Greater =>
+ return Eval_Logic_Scalar (Left, Right, Match_Gt_Table);
+ when Iir_Predefined_Std_Ulogic_Match_Greater_Equal =>
+ return Eval_Logic_Scalar (Left, Right, Match_Ge_Table);
+ when Iir_Predefined_Std_Ulogic_Match_Less_Equal =>
+ return Eval_Logic_Scalar (Left, Right, Match_Le_Table);
+ when Iir_Predefined_Std_Ulogic_Match_Less =>
+ return Eval_Logic_Scalar (Left, Right, Match_Lt_Table);
+
+ when Iir_Predefined_Std_Ulogic_Array_Match_Equality =>
+ return Eval_Vector_Match (Left, Right, False, Expr);
+ when Iir_Predefined_Std_Ulogic_Array_Match_Inequality =>
+ return Eval_Vector_Match (Left, Right, True, Expr);
+
+ when Iir_Predefined_Ieee_1164_And_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_And_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_And_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, And_Table);
+ when Iir_Predefined_Ieee_1164_Or_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, Or_Table);
+ when Iir_Predefined_Ieee_1164_Xor_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, Xor_Table);
+ when Iir_Predefined_Ieee_1164_Nand_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, Nand_Table);
+ when Iir_Predefined_Ieee_1164_Nor_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, Nor_Table);
+ when Iir_Predefined_Ieee_1164_Xnor_Suv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns_Log
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn_Log =>
+ return Eval_Logic_Vector_Scalar (Left, Right, Xnor_Table);
+
+ when Iir_Predefined_Ieee_1164_And_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_And_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_And_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, And_Table);
+ when Iir_Predefined_Ieee_1164_Or_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, Or_Table);
+ when Iir_Predefined_Ieee_1164_Xor_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, Xor_Table);
+ when Iir_Predefined_Ieee_1164_Nand_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, Nand_Table);
+ when Iir_Predefined_Ieee_1164_Nor_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, Nor_Table);
+ when Iir_Predefined_Ieee_1164_Xnor_Log_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Log_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Log_Sgn =>
+ return Eval_Logic_Vector_Scalar (Right, Left, Xnor_Table);
+
+ when Iir_Predefined_Ieee_1164_Vector_Sll
+ | Iir_Predefined_Ieee_Numeric_Std_Sla_Uns_Int =>
+ return Execute_Shift_Operator
+ (Left, Read_Discrete (Right), Std_Ulogic'Pos('0'),
+ Iir_Predefined_Array_Sll);
+ when Iir_Predefined_Ieee_1164_Vector_Srl
+ | Iir_Predefined_Ieee_Numeric_Std_Sra_Uns_Int =>
+ return Execute_Shift_Operator
+ (Left, Read_Discrete (Right), Std_Ulogic'Pos('0'),
+ Iir_Predefined_Array_Srl);
+ when Iir_Predefined_Ieee_Numeric_Std_Sra_Sgn_Int =>
+ declare
+ Cnt : constant Int64 := Read_Discrete (Right);
+ begin
+ if Cnt >= 0 then
+ return Execute_Shift_Operator
+ (Left, Cnt, Std_Ulogic'Pos('0'), Iir_Predefined_Array_Sra);
+ else
+ return Execute_Shift_Operator
+ (Left, -Cnt, Std_Ulogic'Pos('0'),
+ Iir_Predefined_Array_Sll);
+ end if;
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Sla_Sgn_Int =>
+ declare
+ Cnt : Int64;
+ Op : Iir_Predefined_Shift_Functions;
+ begin
+ Cnt := Read_Discrete (Right);
+ if Cnt >= 0 then
+ Op := Iir_Predefined_Array_Sll;
+ else
+ Cnt := -Cnt;
+ Op :=Iir_Predefined_Array_Sra;
+ end if;
+ return Execute_Shift_Operator
+ (Left, Cnt, Std_Ulogic'Pos('0'), Op);
+ end;
+
+ when Iir_Predefined_Ieee_1164_Vector_Rol
+ | Iir_Predefined_Ieee_Numeric_Std_Rol_Uns_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Rol_Sgn_Int =>
+ return Execute_Shift_Operator
+ (Left, Read_Discrete (Right), Std_Ulogic'Pos('0'),
+ Iir_Predefined_Array_Rol);
+ when Iir_Predefined_Ieee_1164_Vector_Ror
+ | Iir_Predefined_Ieee_Numeric_Std_Ror_Uns_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Ror_Sgn_Int =>
+ return Execute_Shift_Operator
+ (Left, Read_Discrete (Right), Std_Ulogic'Pos('0'),
+ Iir_Predefined_Array_Ror);
when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
end;
- when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Sgn =>
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Nat =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Nat (Left, Right, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
end;
- when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Nat =>
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Nat_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Uns_Nat (Right, Left, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Sgn =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Nat (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Sgn (Left, Right, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Eq_Sgn_Int =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Int (Left, Right, Greater, Expr) = Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Int (Left, Right, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Greater, +Expr) = Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Uns_Uns (Left, Right, Greater, +Expr) /= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Uns_Nat =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Uns_Nat (Left, Right, Greater, +Expr) /= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Nat_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Uns_Nat (Right, Left, Greater, +Expr) /= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ne_Sgn_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Sgn (Left, Right, Greater, +Expr) /= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Less, +Expr) = Greater;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Sgn_Sgn =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Sgn (Left, Right, Less, +Expr) = Greater;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Nat_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Nat_Uns (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Nat_Uns (Left, Right, Less, +Expr) = Greater;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Gt_Uns_Nat =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Nat (Left, Right, Less, Expr) = Greater;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Nat (Left, Right, Less, +Expr) = Greater;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Less, +Expr) = Greater;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Gt_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Greater, Expr) >= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Nat_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Nat_Uns (Left, Right, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Uns_Nat =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Uns_Nat (Left, Right, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Sgn =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) >= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Sgn (Left, Right, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Ge_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Greater, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Uns_Nat =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Nat (Left, Right, Greater, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Nat (Left, Right, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Nat_Uns =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Nat_Uns (Left, Right, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Sgn =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) <= Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Sgn (Left, Right, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Less, +Expr) >= Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Le_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Greater, +Expr) <= Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Uns (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Uns (Left, Right, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Nat =>
declare
Res : Boolean;
begin
- Res := Compare_Uns_Nat (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Uns_Nat (Left, Right, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Nat_Uns =>
declare
Res : Boolean;
begin
- Res := Compare_Nat_Uns (Left, Right, Greater, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Nat_Uns (Left, Right, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
end;
when Iir_Predefined_Ieee_Numeric_Std_Lt_Sgn_Sgn =>
declare
Res : Boolean;
begin
- Res := Compare_Sgn_Sgn (Left, Right, Less, Expr) < Equal;
- return Create_Memory_U8 (Boolean'Pos (Res), Res_Typ);
+ Res := Compare_Sgn_Sgn (Left, Right, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Int_Sgn =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Right, Left, Less, +Expr) > Equal;
+ return Create_Memory_Boolean (Res);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Lt_Sgn_Int =>
+ declare
+ Res : Boolean;
+ begin
+ Res := Compare_Sgn_Int (Left, Right, Greater, +Expr) < Equal;
+ return Create_Memory_Boolean (Res);
end;
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 =>
- return Add_Uns_Uns (Left, Right, Expr);
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Slv_Slv =>
+ return Add_Uns_Uns (Left, Right, +Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int =>
- return Add_Sgn_Int (Left, Read_Discrete (Right), Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Log =>
+ return Add_Uns_Uns (Left, Log_To_Vec (Right, Left), +Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat
- | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Int =>
- return Add_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn =>
- return Add_Sgn_Sgn (Left, Right, Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Log_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Log_Slv =>
+ return Add_Uns_Uns (Log_To_Vec (Left, Right), Right, +Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns =>
- return Sub_Uns_Uns (Left, Right, Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat =>
- return Sub_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Int
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Slv_Nat =>
+ return Add_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Nat_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Int_Slv =>
+ return Add_Uns_Nat (Right, To_Uns64 (Read_Discrete (Left)), +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn
+ | Iir_Predefined_Ieee_Std_Logic_Arith_Add_Sgn_Sgn_Sgn =>
+ return Add_Sgn_Sgn (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int =>
+ return Add_Sgn_Int (Left, Read_Discrete (Right), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Int_Sgn =>
+ return Add_Sgn_Int (Right, Read_Discrete (Left), +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log =>
+ return Add_Sgn_Sgn (Left, Log_To_Vec (Right, Left), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn =>
+ return Add_Sgn_Sgn (Log_To_Vec (Left, Right), Right, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Slv_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Slv =>
+ return Sub_Uns_Uns (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Slv_Nat
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Int =>
+ return Sub_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Nat_Slv
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Int_Slv =>
+ return Sub_Nat_Uns (To_Uns64 (Read_Discrete (Left)), Right, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Log
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Log =>
+ return Sub_Uns_Uns (Left, Log_To_Vec (Right, Left), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Uns
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Log_Slv =>
+ return Sub_Uns_Uns (Log_To_Vec (Left, Right), Right, +Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int =>
- return Sub_Sgn_Int (Left, Read_Discrete (Right), Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Sgn =>
- return Sub_Sgn_Sgn (Left, Right, Expr);
+ return Sub_Sgn_Sgn (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int =>
+ return Sub_Sgn_Int (Left, Read_Discrete (Right), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Int_Sgn =>
+ return Sub_Int_Sgn (Read_Discrete (Left), Right, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log =>
+ return Sub_Sgn_Sgn (Left, Log_To_Vec (Right, Left), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn =>
+ return Sub_Sgn_Sgn (Log_To_Vec (Left, Right), Right, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns =>
- return Mul_Uns_Uns (Left, Right, Expr);
+ return Mul_Uns_Uns (Left, Right, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Nat_Uns =>
- return Mul_Nat_Uns (To_Uns64 (Read_Discrete (Left)), Right, Expr);
+ return Mul_Nat_Uns (To_Uns64 (Read_Discrete (Left)), Right, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Nat =>
- return Mul_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), Expr);
+ return Mul_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn =>
- return Mul_Sgn_Sgn (Left, Right, Expr);
+ return Mul_Sgn_Sgn (Left, Right, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Int =>
- return Mul_Sgn_Int (Left, Read_Discrete (Right), Expr);
+ return Mul_Sgn_Int (Left, Read_Discrete (Right), +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Mul_Int_Sgn =>
- return Mul_Int_Sgn (Read_Discrete (Left), Right, Expr);
+ return Mul_Int_Sgn (Read_Discrete (Left), Right, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Uns =>
- return Div_Uns_Uns (Left, Right, Expr);
+ return Div_Uns_Uns (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Nat =>
+ return Div_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Nat_Uns =>
+ return Div_Nat_Uns (To_Uns64 (Read_Discrete (Left)), Right, +Expr);
+
when Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Sgn =>
- return Div_Sgn_Sgn (Left, Right, Expr);
+ return Div_Sgn_Sgn (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Int_Sgn =>
+ return Div_Int_Sgn (Read_Discrete (Left), Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Int =>
+ return Div_Sgn_Int (Left, Read_Discrete (Right), +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Mod_Uns_Uns =>
+ return Rem_Uns_Uns (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Mod_Uns_Nat =>
+ return Rem_Uns_Nat (Left, To_Uns64 (Read_Discrete (Right)), +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Mod_Nat_Uns =>
+ return Rem_Nat_Uns (To_Uns64 (Read_Discrete (Left)), Right, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Sgn_Sgn =>
+ return Rem_Sgn_Sgn (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Int_Sgn =>
+ return Rem_Int_Sgn (Read_Discrete (Left), Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Rem_Sgn_Int =>
+ return Rem_Sgn_Int (Left, Read_Discrete (Right), +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Sgn_Sgn =>
+ return Mod_Sgn_Sgn (Left, Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Int_Sgn =>
+ return Mod_Int_Sgn (Read_Discrete (Left), Right, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Mod_Sgn_Int =>
+ return Mod_Sgn_Int (Left, Read_Discrete (Right), +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Srl_Uns_Int
| Iir_Predefined_Ieee_Numeric_Std_Srl_Sgn_Int =>
@@ -649,7 +1308,59 @@ package body Synth.Vhdl_Eval is
end if;
end;
- when Iir_Predefined_Ieee_Math_Real_Pow =>
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Uns_Uns =>
+ declare
+ Res : Std_Ulogic;
+ begin
+ Res := Match_Eq_Vec_Vec (Left, Right, False, +Expr);
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Res_Typ);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Uns_Uns =>
+ declare
+ Res : Std_Ulogic;
+ begin
+ Res := Match_Eq_Vec_Vec (Left, Right, False, +Expr);
+ Res := Not_Table (Res);
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Res_Typ);
+ end;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Uns_Uns =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Lt, False, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Sgn_Sgn =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Lt, True, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Le_Uns_Uns =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Le, False, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Le_Sgn_Sgn =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Le, True, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Uns_Uns =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Gt, False, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Sgn_Sgn =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Gt, True, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Uns_Uns =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Ge, False, +Expr);
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Sgn_Sgn =>
+ return Match_Cmp_Vec_Vec (Left, Right, Map_Ge, True, +Expr);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Eq_Sgn_Sgn =>
+ declare
+ Res : Std_Ulogic;
+ begin
+ Res := Match_Eq_Vec_Vec (Left, Right, True, +Expr);
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Res_Typ);
+ end;
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Ne_Sgn_Sgn =>
+ declare
+ Res : Std_Ulogic;
+ begin
+ Res := Match_Eq_Vec_Vec (Left, Right, True, +Expr);
+ Res := Not_Table (Res);
+ return Create_Memory_U8 (Std_Ulogic'Pos (Res), Res_Typ);
+ end;
+
+ when Iir_Predefined_Ieee_Math_Real_Pow_Real_Real =>
declare
function Pow (L, R : Fp64) return Fp64;
pragma Import (C, Pow);
@@ -658,9 +1369,18 @@ package body Synth.Vhdl_Eval is
(Pow (Read_Fp64 (Left), Read_Fp64 (Right)), Res_Typ);
end;
+ when Iir_Predefined_Ieee_Math_Real_Mod =>
+ declare
+ function Fmod (L, R : Fp64) return Fp64;
+ pragma Import (C, Fmod);
+ begin
+ return Create_Memory_Fp64
+ (Fmod (Read_Fp64 (Left), Read_Fp64 (Right)), Res_Typ);
+ end;
+
when others =>
Error_Msg_Synth
- (+Expr, "synth_static_dyadic_predefined: unhandled "
+ (+Expr, "eval_static_dyadic_predefined: unhandled "
& Iir_Predefined_Functions'Image (Def));
return Null_Memtyp;
end case;
@@ -682,10 +1402,12 @@ package body Synth.Vhdl_Eval is
return Res;
end Eval_Vector_Monadic;
- function Eval_Vector_Reduce
- (Init : Std_Ulogic; Vec : Memtyp; Op : Table_2d) return Memtyp
+ function Eval_Vector_Reduce (Init : Std_Ulogic;
+ Vec : Memtyp;
+ Op : Table_2d;
+ Neg : Boolean) return Memtyp
is
- El_Typ : constant Type_Acc := Vec.Typ.Vec_El;
+ El_Typ : constant Type_Acc := Vec.Typ.Arr_El;
Res : Std_Ulogic;
begin
Res := Init;
@@ -697,9 +1419,160 @@ package body Synth.Vhdl_Eval is
end;
end loop;
+ if Neg then
+ Res := Not_Table (Res);
+ end if;
+
return Create_Memory_U8 (Std_Ulogic'Pos (Res), El_Typ);
end Eval_Vector_Reduce;
+ function Eval_TF_Vector_Monadic (Vec : Memtyp) return Memtyp
+ is
+ Len : constant Iir_Index32 := Vec_Length (Vec.Typ);
+ Res : Memtyp;
+ begin
+ Res := Create_Memory (Create_Res_Bound (Vec.Typ));
+ for I in 1 .. Uns32 (Len) loop
+ declare
+ V : constant Boolean :=
+ Boolean'Val (Read_U8 (Vec.Mem + Size_Type (I - 1)));
+ begin
+ Write_U8 (Res.Mem + Size_Type (I - 1), Boolean'Pos (not V));
+ end;
+ end loop;
+ return Res;
+ end Eval_TF_Vector_Monadic;
+
+ function Eval_TF_Vector_Reduce (Init : Boolean;
+ Neg : Boolean;
+ Vec : Memtyp;
+ Op : Tf_Table_2d) return Memtyp
+ is
+ El_Typ : constant Type_Acc := Vec.Typ.Arr_El;
+ Res : Boolean;
+ begin
+ Res := Init;
+ for I in 1 .. Size_Type (Vec.Typ.Abound.Len) loop
+ declare
+ V : constant Boolean := Boolean'Val (Read_U8 (Vec.Mem + (I - 1)));
+ begin
+ Res := Op (Res, V);
+ end;
+ end loop;
+
+ return Create_Memory_U8 (Boolean'Pos (Res xor Neg), El_Typ);
+ end Eval_TF_Vector_Reduce;
+
+ function Eval_Vector_Maximum (Vec : Memtyp) return Memtyp
+ is
+ Etyp : constant Type_Acc := Vec.Typ.Arr_El;
+ Len : constant Uns32 := Vec.Typ.Abound.Len;
+ begin
+ case Etyp.Kind is
+ when Type_Logic
+ | Type_Bit
+ | Type_Discrete =>
+ declare
+ Res : Int64;
+ V : Int64;
+ begin
+ case Etyp.Drange.Dir is
+ when Dir_To =>
+ Res := Etyp.Drange.Left;
+ when Dir_Downto =>
+ Res := Etyp.Drange.Right;
+ end case;
+
+ for I in 1 .. Len loop
+ V := Read_Discrete
+ (Vec.Mem + Size_Type (I - 1) * Etyp.Sz, Etyp);
+ if V > Res then
+ Res := V;
+ end if;
+ end loop;
+ return Create_Memory_Discrete (Res, Etyp);
+ end;
+ when Type_Float =>
+ declare
+ Res : Fp64;
+ V : Fp64;
+ begin
+ case Etyp.Frange.Dir is
+ when Dir_To =>
+ Res := Etyp.Frange.Left;
+ when Dir_Downto =>
+ Res := Etyp.Frange.Right;
+ end case;
+
+ for I in 1 .. Len loop
+ V := Read_Fp64
+ (Vec.Mem + Size_Type (I - 1) * Etyp.Sz);
+ if V > Res then
+ Res := V;
+ end if;
+ end loop;
+ return Create_Memory_Fp64 (Res, Etyp);
+ end;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Eval_Vector_Maximum;
+
+ function Eval_Vector_Minimum (Vec : Memtyp) return Memtyp
+ is
+ Etyp : constant Type_Acc := Vec.Typ.Arr_El;
+ Len : constant Uns32 := Vec.Typ.Abound.Len;
+ begin
+ case Etyp.Kind is
+ when Type_Logic
+ | Type_Bit
+ | Type_Discrete =>
+ declare
+ Res : Int64;
+ V : Int64;
+ begin
+ case Etyp.Drange.Dir is
+ when Dir_To =>
+ Res := Etyp.Drange.Right;
+ when Dir_Downto =>
+ Res := Etyp.Drange.Left;
+ end case;
+
+ for I in 1 .. Len loop
+ V := Read_Discrete
+ (Vec.Mem + Size_Type (I - 1) * Etyp.Sz, Etyp);
+ if V < Res then
+ Res := V;
+ end if;
+ end loop;
+ return Create_Memory_Discrete (Res, Etyp);
+ end;
+ when Type_Float =>
+ declare
+ Res : Fp64;
+ V : Fp64;
+ begin
+ case Etyp.Frange.Dir is
+ when Dir_To =>
+ Res := Etyp.Frange.Right;
+ when Dir_Downto =>
+ Res := Etyp.Frange.Left;
+ end case;
+
+ for I in 1 .. Len loop
+ V := Read_Fp64
+ (Vec.Mem + Size_Type (I - 1) * Etyp.Sz);
+ if V < Res then
+ Res := V;
+ end if;
+ end loop;
+ return Create_Memory_Fp64 (Res, Etyp);
+ end;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Eval_Vector_Minimum;
+
function Eval_Static_Monadic_Predefined (Imp : Node;
Operand : Memtyp;
Expr : Node) return Memtyp
@@ -712,6 +1585,9 @@ package body Synth.Vhdl_Eval is
| Iir_Predefined_Bit_Not =>
return Create_Memory_U8 (1 - Read_U8 (Operand), Operand.Typ);
+ when Iir_Predefined_Bit_Condition =>
+ return Create_Memory_U8 (Read_U8 (Operand), Operand.Typ);
+
when Iir_Predefined_Integer_Negation
| Iir_Predefined_Physical_Negation =>
return Create_Memory_Discrete
@@ -719,7 +1595,7 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Integer_Absolute
| Iir_Predefined_Physical_Absolute =>
return Create_Memory_Discrete
- (abs Read_Discrete(Operand), Operand.Typ);
+ (abs Read_Discrete (Operand), Operand.Typ);
when Iir_Predefined_Integer_Identity
| Iir_Predefined_Physical_Identity =>
return Operand;
@@ -731,6 +1607,27 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Floating_Absolute =>
return Create_Memory_Fp64 (abs Read_Fp64 (Operand), Operand.Typ);
+ when Iir_Predefined_Vector_Maximum =>
+ return Eval_Vector_Maximum (Operand);
+ when Iir_Predefined_Vector_Minimum =>
+ return Eval_Vector_Minimum (Operand);
+
+ when Iir_Predefined_TF_Array_Not =>
+ return Eval_TF_Vector_Monadic (Operand);
+
+ when Iir_Predefined_TF_Reduction_Or =>
+ return Eval_TF_Vector_Reduce (False, False, Operand, Tf_2d_Or);
+ when Iir_Predefined_TF_Reduction_And =>
+ return Eval_TF_Vector_Reduce (True, False, Operand, Tf_2d_And);
+ when Iir_Predefined_TF_Reduction_Xor =>
+ return Eval_TF_Vector_Reduce (False, False, Operand, Tf_2d_Xor);
+ when Iir_Predefined_TF_Reduction_Nor =>
+ return Eval_TF_Vector_Reduce (False, True, Operand, Tf_2d_Or);
+ when Iir_Predefined_TF_Reduction_Nand =>
+ return Eval_TF_Vector_Reduce (True, True, Operand, Tf_2d_And);
+ when Iir_Predefined_TF_Reduction_Xnor =>
+ return Eval_TF_Vector_Reduce (False, True, Operand, Tf_2d_Xor);
+
when Iir_Predefined_Ieee_1164_Condition_Operator =>
-- Constant std_logic: need to convert.
declare
@@ -743,9 +1640,9 @@ package body Synth.Vhdl_Eval is
end;
when Iir_Predefined_Ieee_Numeric_Std_Neg_Sgn =>
- return Neg_Vec (Operand, Expr);
+ return Neg_Vec (Operand, +Expr);
when Iir_Predefined_Ieee_Numeric_Std_Abs_Sgn =>
- return Abs_Vec (Operand, Expr);
+ return Abs_Vec (Operand, +Expr);
when Iir_Predefined_Ieee_1164_Vector_Not
| Iir_Predefined_Ieee_Numeric_Std_Not_Uns
@@ -757,25 +1654,43 @@ package body Synth.Vhdl_Eval is
(Std_Ulogic'Pos (Not_Table (Read_Std_Logic (Operand.Mem, 0))),
Operand.Typ);
- when Iir_Predefined_Ieee_Numeric_Std_And_Uns =>
- return Eval_Vector_Reduce ('1', Operand, And_Table);
+ when Iir_Predefined_Ieee_1164_And_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_And_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_And_Sgn =>
+ return Eval_Vector_Reduce ('1', Operand, And_Table, False);
+ when Iir_Predefined_Ieee_1164_Nand_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn =>
+ return Eval_Vector_Reduce ('1', Operand, And_Table, True);
when Iir_Predefined_Ieee_1164_Or_Suv
- | Iir_Predefined_Ieee_Numeric_Std_Or_Uns =>
- return Eval_Vector_Reduce ('0', Operand, Or_Table);
- when Iir_Predefined_Ieee_1164_Xor_Suv =>
- return Eval_Vector_Reduce ('0', Operand, Xor_Table);
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Or_Sgn =>
+ return Eval_Vector_Reduce ('0', Operand, Or_Table, False);
+ when Iir_Predefined_Ieee_1164_Nor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn =>
+ return Eval_Vector_Reduce ('0', Operand, Or_Table, True);
+
+ when Iir_Predefined_Ieee_1164_Xor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn =>
+ return Eval_Vector_Reduce ('0', Operand, Xor_Table, False);
+ when Iir_Predefined_Ieee_1164_Xnor_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn =>
+ return Eval_Vector_Reduce ('0', Operand, Xor_Table, True);
when others =>
Error_Msg_Synth
- (+Expr, "synth_static_monadic_predefined: unhandled "
+ (+Expr, "eval_static_monadic_predefined: unhandled "
& Iir_Predefined_Functions'Image (Def));
raise Internal_Error;
end case;
end Eval_Static_Monadic_Predefined;
- function Eval_To_Vector (Arg : Uns64; Sz : Int64; Res_Type : Type_Acc)
- return Memtyp
+ function Eval_To_Log_Vector (Arg : Uns64; Sz : Int64; Res_Type : Type_Acc)
+ return Memtyp
is
Len : constant Iir_Index32 := Iir_Index32 (Sz);
El_Type : constant Type_Acc := Get_Array_Element (Res_Type);
@@ -791,7 +1706,25 @@ package body Synth.Vhdl_Eval is
Std_Ulogic'Val (Std_Logic_0_Pos + B));
end loop;
return Res;
- end Eval_To_Vector;
+ end Eval_To_Log_Vector;
+
+ function Eval_To_Bit_Vector (Arg : Uns64; Sz : Int64; Res_Type : Type_Acc)
+ return Memtyp
+ is
+ Len : constant Size_Type := Size_Type (Sz);
+ El_Type : constant Type_Acc := Get_Array_Element (Res_Type);
+ Res : Memtyp;
+ Bnd : Type_Acc;
+ B : Uns64;
+ begin
+ Bnd := Create_Vec_Type_By_Length (Width (Sz), El_Type);
+ Res := Create_Memory (Bnd);
+ for I in 1 .. Len loop
+ B := Shift_Right_Arithmetic (Arg, Natural (I - 1)) and 1;
+ Write_U8 (Res.Mem + (Len - I), Ghdl_U8 (B));
+ end loop;
+ return Res;
+ end Eval_To_Bit_Vector;
function Eval_Unsigned_To_Integer (Arg : Memtyp; Loc : Node) return Int64
is
@@ -853,6 +1786,193 @@ package body Synth.Vhdl_Eval is
return To_Int64 (Res);
end Eval_Signed_To_Integer;
+ function Eval_Array_Char_To_String (Param : Memtyp;
+ Res_Typ : Type_Acc;
+ Imp : Node) return Memtyp
+ is
+ use Vhdl.Utils;
+ use Name_Table;
+ Len : constant Uns32 := Param.Typ.Abound.Len;
+ Elt : constant Type_Acc := Param.Typ.Arr_El;
+ Etype : constant Node := Get_Base_Type
+ (Get_Element_Subtype
+ (Get_Type (Get_Interface_Declaration_Chain (Imp))));
+ pragma Assert (Get_Kind (Etype) = Iir_Kind_Enumeration_Type_Definition);
+ Enums : constant Iir_Flist := Get_Enumeration_Literal_List (Etype);
+ Lit : Node;
+ Lit_Id : Name_Id;
+ Bnd : Bound_Type;
+ Res_St : Type_Acc;
+ Res : Memtyp;
+ V : Int64;
+ begin
+ Bnd := Elab.Vhdl_Types.Create_Bounds_From_Length
+ (Res_Typ.Uarr_Idx.Drange, Iir_Index32 (Len));
+ Res_St := Create_Onedimensional_Array_Subtype
+ (Res_Typ, Bnd, Res_Typ.Uarr_El);
+ Res := Create_Memory (Res_St);
+ for I in 1 .. Len loop
+ V := Read_Discrete (Param.Mem + Size_Type (I - 1) * Elt.Sz, Elt);
+ Lit := Get_Nth_Element (Enums, Natural (V));
+ Lit_Id := Get_Identifier (Lit);
+ pragma Assert (Is_Character (Lit_Id));
+ Write_U8 (Res.Mem + Size_Type (I - 1),
+ Character'Pos (Get_Character (Lit_Id)));
+ end loop;
+ return Res;
+ end Eval_Array_Char_To_String;
+
+ function String_To_Memtyp (Str : String; Styp : Type_Acc) return Memtyp
+ is
+ Len : constant Natural := Str'Length;
+ Bnd : Bound_Type;
+ Typ : Type_Acc;
+ Res : Memtyp;
+ begin
+ Bnd := (Dir => Dir_To, Left => 1, Right => Int32 (Len),
+ Len => Uns32 (Len));
+ Typ := Create_Array_Type (Bnd, True, Styp.Uarr_El);
+
+ Res := Create_Memory (Typ);
+ for I in Str'Range loop
+ Write_U8 (Res.Mem + Size_Type (I - Str'First),
+ Character'Pos (Str (I)));
+ end loop;
+ return Res;
+ end String_To_Memtyp;
+
+ function Eval_Enum_To_String (Param : Memtyp;
+ Res_Typ : Type_Acc;
+ Imp : Node) return Memtyp
+ is
+ use Vhdl.Utils;
+ use Name_Table;
+ Etype : constant Node := Get_Base_Type
+ (Get_Type (Get_Interface_Declaration_Chain (Imp)));
+ pragma Assert (Get_Kind (Etype) = Iir_Kind_Enumeration_Type_Definition);
+ Enums : constant Iir_Flist := Get_Enumeration_Literal_List (Etype);
+ Lit : Node;
+ Lit_Id : Name_Id;
+ V : Int64;
+ C : String (1 .. 1);
+ begin
+ V := Read_Discrete (Param.Mem, Param.Typ);
+ Lit := Get_Nth_Element (Enums, Natural (V));
+ Lit_Id := Get_Identifier (Lit);
+ if Is_Character (Lit_Id) then
+ C (1) := Get_Character (Lit_Id);
+ return String_To_Memtyp (C, Res_Typ);
+ else
+ return String_To_Memtyp (Image (Lit_Id), Res_Typ);
+ end if;
+ end Eval_Enum_To_String;
+
+ Hex_Chars : constant array (Natural range 0 .. 15) of Character :=
+ "0123456789ABCDEF";
+
+ function Eval_Bit_Vector_To_String (Val : Memtyp;
+ Res_Typ : Type_Acc;
+ Log_Base : Natural) return Memtyp
+ is
+ Base : constant Natural := 2 ** Log_Base;
+ Blen : constant Natural := Natural (Val.Typ.Abound.Len);
+ Str : String (1 .. (Blen + Log_Base - 1) / Log_Base);
+ Pos : Natural;
+ V : Natural;
+ N : Natural;
+ begin
+ V := 0;
+ N := 1;
+ Pos := Str'Last;
+ for I in 1 .. Blen loop
+ V := V + Natural (Read_U8 (Val.Mem + Size_Type (Blen - I))) * N;
+ N := N * 2;
+ if N = Base or else I = Blen then
+ Str (Pos) := Hex_Chars (V);
+ Pos := Pos - 1;
+ N := 1;
+ V := 0;
+ end if;
+ end loop;
+ return String_To_Memtyp (Str, Res_Typ);
+ end Eval_Bit_Vector_To_String;
+
+ function Eval_Logic_Vector_To_String (Val : Memtyp;
+ Res_Typ : Type_Acc;
+ Is_Signed : Boolean;
+ Log_Base : Natural) return Memtyp
+ is
+ Base : constant Natural := 2 ** Log_Base;
+ Blen : constant Uns32 := Val.Typ.Abound.Len;
+ Str : String (1 .. (Natural (Blen) + Log_Base - 1) / Log_Base);
+ Pos : Natural;
+ D : Std_Ulogic;
+ V : Natural;
+ N : Natural;
+ Has_X, Has_Z, Has_D : Boolean;
+ begin
+ V := 0;
+ N := 1;
+ Has_X := False;
+ Has_Z := False;
+ Has_D := False;
+ Pos := Str'Last;
+ for I in 1 .. Blen loop
+ D := Read_Std_Logic (Val.Mem, Blen - I);
+ case D is
+ when '0' | 'L' =>
+ Has_D := True;
+ when '1' | 'H' =>
+ Has_D := True;
+ V := V + N;
+ when 'Z' | 'W' =>
+ Has_Z := True;
+ when 'X' | 'U' | '-' =>
+ Has_X := True;
+ end case;
+ N := N * 2;
+ if N = Base or else I = Blen then
+ if Has_X or (Has_Z and Has_D) then
+ Str (Pos) := 'X';
+ elsif Has_Z then
+ Str (Pos) := 'Z';
+ else
+ if Is_Signed and N < Base and (D = '1' or D = 'H') then
+ -- Sign extend.
+ loop
+ V := V + N;
+ N := N * 2;
+ exit when N = Base;
+ end loop;
+ end if;
+ Str (Pos) := Hex_Chars (V);
+ end if;
+ Pos := Pos - 1;
+ N := 1;
+ V := 0;
+ Has_X := False;
+ Has_Z := False;
+ Has_D := False;
+ end if;
+ end loop;
+ return String_To_Memtyp (Str, Res_Typ);
+ end Eval_Logic_Vector_To_String;
+
+ function Eval_To_X01 (Val : Memtyp; Map : Table_1d) return Memtyp
+ is
+ Len : constant Uns32 := Val.Typ.Abound.Len;
+ Res : Memtyp;
+ B : Std_Ulogic;
+ begin
+ Res := Create_Memory (Create_Res_Bound (Val.Typ));
+ for I in 1 .. Len loop
+ B := Read_Std_Logic (Val.Mem, I - 1);
+ B := Map (B);
+ Write_Std_Logic (Res.Mem, I - 1, B);
+ end loop;
+ return Res;
+ end Eval_To_X01;
+
function Eval_Static_Predefined_Function_Call (Param1 : Valtyp;
Param2 : Valtyp;
Res_Typ : Type_Acc;
@@ -863,6 +1983,29 @@ package body Synth.Vhdl_Eval is
Get_Implicit_Definition (Imp);
begin
case Def is
+ when Iir_Predefined_Physical_Minimum
+ | Iir_Predefined_Integer_Minimum
+ | Iir_Predefined_Enum_Minimum =>
+ return Create_Memory_Discrete
+ (Int64'Min (Read_Discrete (Param1), Read_Discrete (Param2)),
+ Res_Typ);
+ when Iir_Predefined_Floating_Maximum =>
+ return Create_Memory_Fp64
+ (Fp64'Max (Read_Fp64 (Param1), Read_Fp64 (Param2)), Res_Typ);
+ when Iir_Predefined_Physical_Maximum
+ | Iir_Predefined_Integer_Maximum
+ | Iir_Predefined_Enum_Maximum =>
+ return Create_Memory_Discrete
+ (Int64'Max (Read_Discrete (Param1), Read_Discrete (Param2)),
+ Res_Typ);
+ when Iir_Predefined_Floating_Minimum =>
+ return Create_Memory_Fp64
+ (Fp64'Min (Read_Fp64 (Param1), Read_Fp64 (Param2)), Res_Typ);
+
+ when Iir_Predefined_Now_Function =>
+ return Create_Memory_Discrete
+ (Int64 (Grt.Vhdl_Types.Current_Time), Res_Typ);
+
when Iir_Predefined_Endfile =>
declare
Res : Boolean;
@@ -871,20 +2014,143 @@ package body Synth.Vhdl_Eval is
return Create_Memory_U8 (Boolean'Pos (Res), Boolean_Type);
end;
+ when Iir_Predefined_Integer_To_String =>
+ declare
+ Str : String (1 .. 21);
+ First : Natural;
+ begin
+ Grt.To_Strings.To_String
+ (Str, First, Ghdl_I64 (Read_Discrete (Param1)));
+ return String_To_Memtyp (Str (First .. Str'Last), Res_Typ);
+ end;
+ when Iir_Predefined_Enum_To_String =>
+ return Eval_Enum_To_String (Get_Memtyp (Param1), Res_Typ, Imp);
+ when Iir_Predefined_Floating_To_String =>
+ declare
+ Str : String (1 .. 24);
+ Last : Natural;
+ begin
+ Grt.To_Strings.To_String
+ (Str, Last, Ghdl_F64 (Read_Fp64 (Param1)));
+ return String_To_Memtyp (Str (Str'First .. Last), Res_Typ);
+ end;
+ when Iir_Predefined_Real_To_String_Digits =>
+ declare
+ Str : Grt.To_Strings.String_Real_Format;
+ Last : Natural;
+ Val : Ghdl_F64;
+ Dig : Ghdl_I32;
+ begin
+ Val := Ghdl_F64 (Read_Fp64 (Param1));
+ Dig := Ghdl_I32 (Read_Discrete (Param2));
+ Grt.To_Strings.To_String (Str, Last, Val, Dig);
+ return String_To_Memtyp (Str (Str'First .. Last), Res_Typ);
+ end;
+ when Iir_Predefined_Real_To_String_Format =>
+ declare
+ Format : String (1 .. Natural (Param2.Typ.Abound.Len) + 1);
+ Str : Grt.To_Strings.String_Real_Format;
+ Last : Natural;
+ begin
+ -- Copy format
+ for I in 1 .. Param2.Typ.Abound.Len loop
+ Format (Positive (I)) := Character'Val
+ (Read_U8 (Param2.Val.Mem + Size_Type (I - 1)));
+ end loop;
+ Format (Format'Last) := ASCII.NUL;
+ Grt.To_Strings.To_String
+ (Str, Last, Ghdl_F64 (Read_Fp64 (Param1)),
+ To_Ghdl_C_String (Format'Address));
+ return String_To_Memtyp (Str (Str'First .. Last), Res_Typ);
+ end;
+
+ when Iir_Predefined_Physical_To_String =>
+ declare
+ Phys_Type : constant Node :=
+ Get_Type (Get_Interface_Declaration_Chain (Imp));
+ Id : constant Name_Id :=
+ Get_Identifier (Get_Primary_Unit (Phys_Type));
+ Str : String (1 .. 21);
+ First : Natural;
+ begin
+ Grt.To_Strings.To_String
+ (Str, First, Ghdl_I64 (Read_Discrete (Param1)));
+ return String_To_Memtyp
+ (Str (First .. Str'Last) & ' ' & Name_Table.Image (Id),
+ Res_Typ);
+ end;
+ when Iir_Predefined_Time_To_String_Unit =>
+ declare
+ Time_Type : constant Node :=
+ Get_Type (Get_Interface_Declaration_Chain (Imp));
+ Str : Grt.To_Strings.String_Time_Unit;
+ First : Natural;
+ Unit : Iir;
+ Uval : Int64;
+ begin
+ Uval := Read_Discrete (Param2);
+ Unit := Get_Unit_Chain (Time_Type);
+ while Unit /= Null_Iir loop
+ exit when Vhdl.Evaluation.Get_Physical_Value (Unit) = Uval;
+ Unit := Get_Chain (Unit);
+ end loop;
+ if Unit = Null_Iir then
+ Error_Msg_Synth
+ (+Expr, "to_string for time called with wrong unit");
+ end if;
+ Grt.To_Strings.To_String (Str, First,
+ Ghdl_I64 (Read_Discrete (Param1)),
+ Ghdl_I64 (Uval));
+ return String_To_Memtyp
+ (Str (First .. Str'Last) & ' '
+ & Name_Table.Image (Get_Identifier (Unit)),
+ Res_Typ);
+ end;
+
+ when Iir_Predefined_Array_Char_To_String =>
+ return Eval_Array_Char_To_String
+ (Get_Memtyp (Param1), Res_Typ, Imp);
+
+ when Iir_Predefined_Bit_Vector_To_Hstring =>
+ return Eval_Bit_Vector_To_String (Get_Memtyp (Param1), Res_Typ, 4);
+ when Iir_Predefined_Bit_Vector_To_Ostring =>
+ return Eval_Bit_Vector_To_String (Get_Memtyp (Param1), Res_Typ, 3);
+
+ when Iir_Predefined_Std_Env_Resolution_Limit =>
+ return Create_Memory_Discrete (1, Res_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Bit_Touns_Nat_Nat_Uns =>
+ return Eval_To_Bit_Vector
+ (Uns64 (Read_Discrete (Param1)), Read_Discrete (Param2),
+ Res_Typ);
+
when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Int
- | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Slv_Nat_Nat_Slv =>
- return Eval_To_Vector
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Slv_Nat_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Suv_Nat_Nat =>
+ return Eval_To_Log_Vector
(Uns64 (Read_Discrete (Param1)), Read_Discrete (Param2),
Res_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Slv_Nat_Slv
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Suv_Nat_Suv =>
+ return Eval_To_Log_Vector
+ (Uns64 (Read_Discrete (Param1)), Int64 (Param2.Typ.Abound.Len),
+ Res_Typ);
when Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Nat_Sgn
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Int =>
- return Eval_To_Vector
+ return Eval_To_Log_Vector
(To_Uns64 (Read_Discrete (Param1)), Read_Discrete (Param2),
Res_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Sgn_Sgn =>
+ return Eval_To_Log_Vector
+ (To_Uns64 (Read_Discrete (Param1)),
+ Int64 (Param2.Typ.Abound.Len),
+ Res_Typ);
when Iir_Predefined_Ieee_Numeric_Std_Toint_Uns_Nat
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Integer_Uns
- | Iir_Predefined_Ieee_Std_Logic_Unsigned_Conv_Integer =>
+ | Iir_Predefined_Ieee_Std_Logic_Unsigned_Conv_Integer
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_To_Integer_Slv_Nat =>
-- UNSIGNED to Natural.
return Create_Memory_Discrete
(Eval_Unsigned_To_Integer (Get_Memtyp (Param1), Expr), Res_Typ);
@@ -896,11 +2162,13 @@ package body Synth.Vhdl_Eval is
return Get_Memtyp (Param1);
when Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Uns_Nat
- | Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Sgn_Nat =>
+ | Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Sgn_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Shift_Left =>
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
False, False);
- when Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Uns_Nat =>
+ when Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Shift_Right =>
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
True, False);
@@ -908,12 +2176,31 @@ package body Synth.Vhdl_Eval is
return Shift_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)),
True, True);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Sgn_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Rotate_Left =>
+ return Rotate_Vec
+ (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), False);
+ when Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Sgn_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Rotate_Right =>
+ return Rotate_Vec
+ (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), True);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Resize_Slv_Nat =>
+ return Resize_Vec
+ (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), False);
+ when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Resize_Slv_Slv =>
+ return Resize_Vec
+ (Get_Memtyp (Param1), Param2.Typ.Abound.Len, False);
when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat =>
return Resize_Vec
(Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), True);
- when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat =>
+ when Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Sgn =>
return Resize_Vec
- (Get_Memtyp (Param1), Uns32 (Read_Discrete (Param2)), False);
+ (Get_Memtyp (Param1), Param2.Typ.Abound.Len, True);
when Iir_Predefined_Ieee_1164_To_Stdulogic =>
declare
@@ -931,23 +2218,26 @@ package body Synth.Vhdl_Eval is
B := To_X01 (B);
return Create_Memory_U8 (Std_Ulogic'Pos (B), Res_Typ);
end;
- when Iir_Predefined_Ieee_1164_To_X01_Slv =>
+ when Iir_Predefined_Ieee_1164_To_X01Z_Log =>
declare
- El_Type : constant Type_Acc := Get_Array_Element (Res_Typ);
- Res : Memtyp;
- Bnd : Type_Acc;
B : Std_Ulogic;
begin
- Bnd := Create_Vec_Type_By_Length
- (Uns32 (Vec_Length (Param1.Typ)), El_Type);
- Res := Create_Memory (Bnd);
- for I in 1 .. Uns32 (Vec_Length (Param1.Typ)) loop
- B := Read_Std_Logic (Param1.Val.Mem, I - 1);
- B := To_X01 (B);
- Write_Std_Logic (Res.Mem, I - 1, B);
- end loop;
- return Res;
+ B := Read_Std_Logic (Param1.Val.Mem, 0);
+ B := Map_X01Z (B);
+ return Create_Memory_U8 (Std_Ulogic'Pos (B), Res_Typ);
end;
+ when Iir_Predefined_Ieee_1164_To_X01_Slv
+ | Iir_Predefined_Ieee_Numeric_Std_To_X01_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_To_X01_Sgn =>
+ return Eval_To_X01 (Get_Memtyp (Param1), Map_X01);
+ when Iir_Predefined_Ieee_Numeric_Std_To_X01Z_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_To_X01Z_Sgn
+ | Iir_Predefined_Ieee_1164_To_X01Z_Slv =>
+ return Eval_To_X01 (Get_Memtyp (Param1), Map_X01Z);
+ when Iir_Predefined_Ieee_Numeric_Std_To_UX01_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_To_UX01_Sgn
+ | Iir_Predefined_Ieee_1164_To_UX01_Slv =>
+ return Eval_To_X01 (Get_Memtyp (Param1), Map_UX01);
when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv
| Iir_Predefined_Ieee_1164_To_Stdulogicvector_Bv =>
@@ -967,6 +2257,17 @@ package body Synth.Vhdl_Eval is
return Res;
end;
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Log =>
+ return Create_Memory_Boolean
+ (Match_Eq_Table (Read_Std_Logic (Param1.Val.Mem, 0),
+ Read_Std_Logic (Param2.Val.Mem, 0)) = '1');
+
+ when Iir_Predefined_Ieee_Numeric_Std_Match_Suv
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Match_Sgn =>
+ return Create_Memory_Boolean
+ (Match_Vec (Get_Memtyp (Param1), Get_Memtyp (Param2), +Expr));
+
when Iir_Predefined_Ieee_1164_To_Bit =>
declare
V : Std_Ulogic;
@@ -999,6 +2300,124 @@ package body Synth.Vhdl_Eval is
return Res;
end;
+ when Iir_Predefined_Ieee_1164_To_01_Slv_Log
+ | Iir_Predefined_Ieee_Numeric_Std_To_01_Uns =>
+ declare
+ Len : constant Uns32 := Param1.Typ.Abound.Len;
+ S : Std_Ulogic;
+ Xmap : Std_Ulogic;
+ Res : Memtyp;
+ begin
+ Xmap := Read_Std_Logic (Param2.Val.Mem, 0);
+ Res := Create_Memory (Create_Res_Bound (Param1.Typ));
+ for I in 1 .. Len loop
+ S := Read_Std_Logic (Param1.Val.Mem, I - 1);
+ S := To_X01 (S);
+ if S = 'X' then
+ S := Xmap;
+ end if;
+ Write_Std_Logic (Res.Mem, I - 1, S);
+ end loop;
+ return Res;
+ end;
+
+ when Iir_Predefined_Ieee_1164_Is_X_Log =>
+ declare
+ B : Std_Ulogic;
+ begin
+ B := Read_Std_Logic (Param1.Val.Mem, 0);
+ B := To_X01 (B);
+ return Create_Memory_Boolean (B = 'X');
+ end;
+
+ when Iir_Predefined_Ieee_Numeric_Std_Is_X_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Is_X_Sgn
+ | Iir_Predefined_Ieee_1164_Is_X_Slv =>
+ declare
+ Len : constant Uns32 := Param1.Typ.Abound.Len;
+ Res : Boolean;
+ B : Std_Ulogic;
+ begin
+ Res := False;
+ for I in 1 .. Len loop
+ B := Read_Std_Logic (Param1.Val.Mem, I - 1);
+ if To_X01 (B) = 'X' then
+ Res := True;
+ exit;
+ end if;
+ end loop;
+ return Create_Memory_Boolean (Res);
+ end;
+
+ when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Suv
+ | Iir_Predefined_Ieee_1164_To_Stdulogicvector_Slv =>
+ -- TODO
+ return (Param1.Typ, Param1.Val.Mem);
+
+ when Iir_Predefined_Ieee_1164_To_Hstring
+ | Iir_Predefined_Ieee_Numeric_Std_To_Hstring_Uns =>
+ return Eval_Logic_Vector_To_String
+ (Get_Memtyp (Param1), Res_Typ, False, 4);
+ when Iir_Predefined_Ieee_Numeric_Std_To_Hstring_Sgn =>
+ return Eval_Logic_Vector_To_String
+ (Get_Memtyp (Param1), Res_Typ, True, 4);
+ when Iir_Predefined_Ieee_1164_To_Ostring
+ | Iir_Predefined_Ieee_Numeric_Std_To_Ostring_Uns =>
+ return Eval_Logic_Vector_To_String
+ (Get_Memtyp (Param1), Res_Typ, False, 3);
+ when Iir_Predefined_Ieee_Numeric_Std_To_Ostring_Sgn =>
+ return Eval_Logic_Vector_To_String
+ (Get_Memtyp (Param1), Res_Typ, True, 3);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Uns_Uns =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ False, True);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Uns_Uns =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ False, False);
+ when Iir_Predefined_Ieee_Numeric_Std_Max_Sgn_Sgn =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ True, True);
+ when Iir_Predefined_Ieee_Numeric_Std_Min_Sgn_Sgn =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ True, False);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Find_Rightmost_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Find_Rightmost_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Find_Rightmost =>
+ return Create_Memory_Discrete
+ (Int64 (Find_Rightmost (Get_Memtyp (Param1),
+ Get_Memtyp (Param2))),
+ Res_Typ);
+ when Iir_Predefined_Ieee_Numeric_Std_Find_Leftmost_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Find_Leftmost_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Find_Leftmost =>
+ return Create_Memory_Discrete
+ (Int64 (Find_Leftmost (Get_Memtyp (Param1),
+ Get_Memtyp (Param2))),
+ Res_Typ);
+
+ when Iir_Predefined_Ieee_Numeric_Std_Unsigned_Maximum_Slv_Slv =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ False, True);
+ when Iir_Predefined_Ieee_Numeric_Std_Unsigned_Minimum_Slv_Slv =>
+ return Minmax (Get_Memtyp (Param1), Get_Memtyp (Param2),
+ False, False);
+
+ when Iir_Predefined_Ieee_Math_Real_Sign =>
+ declare
+ Val : constant Fp64 := Read_Fp64 (Param1);
+ Res : Fp64;
+ begin
+ if Val > 0.0 then
+ Res := 1.0;
+ elsif Val < 0.0 then
+ Res := -1.0;
+ else
+ Res := 0.0;
+ end if;
+ return Create_Memory_Fp64 (Res, Res_Typ);
+ end;
when Iir_Predefined_Ieee_Math_Real_Log2 =>
declare
function Log2 (Arg : Fp64) return Fp64;
@@ -1049,10 +2468,10 @@ package body Synth.Vhdl_Eval is
return Create_Memory_Fp64 (Atan (Read_Fp64 (Param1)), Res_Typ);
end;
when others =>
- Error_Msg_Synth
- (+Expr, "unhandled (static) function: "
- & Iir_Predefined_Functions'Image (Def));
- return Null_Memtyp;
+ null;
end case;
+ Error_Msg_Synth (+Expr, "unhandled (static) function: "
+ & Iir_Predefined_Functions'Image (Def));
+ return Null_Memtyp;
end Eval_Static_Predefined_Function_Call;
end Synth.Vhdl_Eval;