aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/synth/elab-vhdl_expr.adb2
-rw-r--r--src/synth/synth-vhdl_eval.adb223
-rw-r--r--src/synth/synth-vhdl_expr.adb2
-rw-r--r--src/vhdl/vhdl-annotations.adb2
-rw-r--r--src/vhdl/vhdl-nodes.ads13
5 files changed, 219 insertions, 23 deletions
diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb
index 488a2984f..20af6434b 100644
--- a/src/synth/elab-vhdl_expr.adb
+++ b/src/synth/elab-vhdl_expr.adb
@@ -1222,7 +1222,7 @@ package body Elab.Vhdl_Expr is
Imp : constant Node := Get_Implementation (Expr);
begin
case Get_Implicit_Definition (Imp) is
- when Iir_Predefined_Pure_Functions
+ when Iir_Predefined_Operators
| Iir_Predefined_Ieee_Numeric_Std_Binary_Operators =>
return Synth_Operator_Function_Call (Syn_Inst, Expr);
when Iir_Predefined_None =>
diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb
index e6fd450e7..5efb1846a 100644
--- a/src/synth/synth-vhdl_eval.adb
+++ b/src/synth/synth-vhdl_eval.adb
@@ -18,9 +18,11 @@
with Types; use Types;
with Types_Utils; use Types_Utils;
+with Name_Table;
with Grt.Types; use Grt.Types;
+with Vhdl.Utils;
with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164;
with Elab.Memtype; use Elab.Memtype;
@@ -47,10 +49,26 @@ 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.Abound.Dir = Dir_Downto
@@ -124,6 +142,82 @@ package body Synth.Vhdl_Eval is
return Res;
end Eval_TF_Array_Element;
+ 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;
+
function Get_Static_Ulogic (Op : Memtyp) return Std_Ulogic is
begin
pragma Assert (Op.Typ.Kind = Type_Logic);
@@ -235,15 +329,23 @@ package body Synth.Vhdl_Eval is
Res_Typ);
when Iir_Predefined_Physical_Minimum
- | Iir_Predefined_Integer_Minimum =>
+ | Iir_Predefined_Integer_Minimum
+ | Iir_Predefined_Enum_Minimum =>
return Create_Memory_Discrete
(Int64'Min (Read_Discrete (Left), Read_Discrete (Right)),
Res_Typ);
+ when Iir_Predefined_Floating_Maximum =>
+ return Create_Memory_Fp64
+ (Fp64'Max (Read_Fp64 (Left), Read_Fp64 (Right)), Res_Typ);
when Iir_Predefined_Physical_Maximum
- | Iir_Predefined_Integer_Maximum =>
+ | Iir_Predefined_Integer_Maximum
+ | Iir_Predefined_Enum_Maximum =>
return Create_Memory_Discrete
(Int64'Max (Read_Discrete (Left), Read_Discrete (Right)),
Res_Typ);
+ when Iir_Predefined_Floating_Minimum =>
+ return Create_Memory_Fp64
+ (Fp64'Min (Read_Fp64 (Left), Read_Fp64 (Right)), Res_Typ);
when Iir_Predefined_Integer_Less_Equal
| Iir_Predefined_Physical_Less_Equal
@@ -417,30 +519,79 @@ package body Synth.Vhdl_Eval is
when Iir_Predefined_Array_Equality
| Iir_Predefined_Record_Equality =>
- return Create_Memory_U8
- (Boolean'Pos (Is_Equal (Left, Right)), Boolean_Type);
+ 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);
+ 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_TF_Array_Xor =>
return Eval_TF_Vector_Dyadic (Left, Right, Tf_2d_Xor, 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 =>
@@ -700,7 +851,7 @@ package body Synth.Vhdl_Eval is
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;
@@ -752,6 +903,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
@@ -759,7 +913,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;
@@ -808,7 +962,7 @@ package body Synth.Vhdl_Eval is
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;
@@ -893,6 +1047,41 @@ 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, Elt);
+ 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 Eval_Static_Predefined_Function_Call (Param1 : Valtyp;
Param2 : Valtyp;
Res_Typ : Type_Acc;
@@ -911,6 +1100,10 @@ package body Synth.Vhdl_Eval is
return Create_Memory_U8 (Boolean'Pos (Res), Boolean_Type);
end;
+ when Iir_Predefined_Array_Char_To_String =>
+ return Eval_Array_Char_To_String
+ (Get_Memtyp (Param1), Res_Typ, Imp);
+
when Iir_Predefined_Std_Env_Resolution_Limit =>
return Create_Memory_Discrete (1, Res_Typ);
diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb
index eee24353f..b8b6b44fa 100644
--- a/src/synth/synth-vhdl_expr.adb
+++ b/src/synth/synth-vhdl_expr.adb
@@ -2059,7 +2059,7 @@ package body Synth.Vhdl_Expr is
Imp : constant Node := Get_Implementation (Expr);
begin
case Get_Implicit_Definition (Imp) is
- when Iir_Predefined_Pure_Functions
+ when Iir_Predefined_Operators
| Iir_Predefined_Ieee_Numeric_Std_Binary_Operators =>
return Synth_Operator_Function_Call (Syn_Inst, Expr);
when Iir_Predefined_None =>
diff --git a/src/vhdl/vhdl-annotations.adb b/src/vhdl/vhdl-annotations.adb
index 07ada1735..21224fe0e 100644
--- a/src/vhdl/vhdl-annotations.adb
+++ b/src/vhdl/vhdl-annotations.adb
@@ -779,7 +779,7 @@ package body Vhdl.Annotations is
when Iir_Kind_Function_Declaration
| Iir_Kind_Procedure_Declaration =>
if (Get_Implicit_Definition (Decl)
- not in Iir_Predefined_Pure_Functions)
+ not in Iir_Predefined_Operators)
and then not Is_Second_Subprogram_Specification (Decl)
then
Annotate_Subprogram_Interfaces_Type (Block_Info, Decl);
diff --git a/src/vhdl/vhdl-nodes.ads b/src/vhdl/vhdl-nodes.ads
index 8e939ad45..83c352479 100644
--- a/src/vhdl/vhdl-nodes.ads
+++ b/src/vhdl/vhdl-nodes.ads
@@ -5547,11 +5547,6 @@ package Vhdl.Nodes is
Iir_Predefined_Bit_Array_Match_Equality,
Iir_Predefined_Bit_Array_Match_Inequality,
- -- LRM08 5.3.2.4 Predefined operations on array types
- Iir_Predefined_Array_Char_To_String,
- Iir_Predefined_Bit_Vector_To_Ostring,
- Iir_Predefined_Bit_Vector_To_Hstring,
-
-- LRM08 9.2.3 Relational Operators
-- IEEE.Std_Logic_1164.Std_Ulogic
Iir_Predefined_Std_Ulogic_Match_Equality,
@@ -5565,6 +5560,11 @@ package Vhdl.Nodes is
Iir_Predefined_Std_Ulogic_Array_Match_Equality,
Iir_Predefined_Std_Ulogic_Array_Match_Inequality,
+ -- LRM08 5.3.2.4 Predefined operations on array types
+ Iir_Predefined_Array_Char_To_String,
+ Iir_Predefined_Bit_Vector_To_Ostring,
+ Iir_Predefined_Bit_Vector_To_Hstring,
+
-- -- Predefined attribute functions.
-- Iir_Predefined_Attribute_Image,
-- Iir_Predefined_Attribute_Value,
@@ -6234,6 +6234,9 @@ package Vhdl.Nodes is
subtype Iir_Predefined_Pure_Functions is Iir_Predefined_Functions range
Iir_Predefined_Boolean_And ..
Iir_Predefined_Functions'Pred (Iir_Predefined_Deallocate);
+ subtype Iir_Predefined_Operators is Iir_Predefined_Functions range
+ Iir_Predefined_Boolean_And ..
+ Iir_Predefined_Std_Ulogic_Array_Match_Inequality;
subtype Iir_Predefined_Impure_Functions is Iir_Predefined_Functions range
Iir_Predefined_Deallocate ..
Iir_Predefined_Functions'Pred (Iir_Predefined_None);