diff options
| author | Tristan Gingold <tgingold@free.fr> | 2022-05-31 05:21:38 +0200 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2022-05-31 18:28:24 +0200 | 
| commit | c8dffe5ce5f11f4da59dba36129c2e754425f047 (patch) | |
| tree | 70baab5f7e911fa193a494bcadc34862d95210c1 | |
| parent | b4e205d65eee6f1065c179f042df1c0fe0ef6d40 (diff) | |
| download | ghdl-c8dffe5ce5f11f4da59dba36129c2e754425f047.tar.gz ghdl-c8dffe5ce5f11f4da59dba36129c2e754425f047.tar.bz2 ghdl-c8dffe5ce5f11f4da59dba36129c2e754425f047.zip | |
synth-vhdl_eval: handle more operations (to_string, match)
| -rw-r--r-- | src/synth/synth-ieee-std_logic_1164.ads | 65 | ||||
| -rw-r--r-- | src/synth/synth-vhdl_eval.adb | 187 | 
2 files changed, 229 insertions, 23 deletions
| diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads index 33a298f81..a98b5537f 100644 --- a/src/synth/synth-ieee-std_logic_1164.ads +++ b/src/synth/synth-ieee-std_logic_1164.ads @@ -105,4 +105,69 @@ package Synth.Ieee.Std_Logic_1164 is     --  UX01ZWLH-        "UX10XX10X"; +   Match_Eq_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUU1",   -- U +      "UXXXXXXX1",   -- X +      "UX10XX101",   -- 0 +      "UX01XX011",   -- 1 +      "UXXXXXXX1",   -- Z +      "UXXXXXXX1",   -- W +      "UX10XX101",   -- L +      "UX01XX011",   -- H +      "111111111"    -- - +     ); + +   Match_Le_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUU1",   -- U +      "UXXXXXXX1",   -- X +      "UX11XX111",   -- 0 +      "UX01XX011",   -- 1 +      "UXXXXXXX1",   -- Z +      "UXXXXXXX1",   -- W +      "UX11XX111",   -- L +      "UX01XX011",   -- H +      "111111111"    -- - +     ); + +   Match_Lt_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUU1",   -- U +      "UXXXXXXX1",   -- X +      "UX01XX011",   -- 0 +      "UX00XX001",   -- 1 +      "UXXXXXXX1",   -- Z +      "UXXXXXXX1",   -- W +      "UX01XX011",   -- L +      "UX00XX001",   -- H +      "111111111"    -- - +     ); + +   Match_Ge_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUU1",   -- U +      "UXXXXXXX1",   -- X +      "UX10XX101",   -- 0 +      "UX11XX111",   -- 1 +      "UXXXXXXX1",   -- Z +      "UXXXXXXX1",   -- W +      "UX10XX101",   -- L +      "UX11XX111",   -- H +      "111111111"    -- - +     ); + +   Match_Gt_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUU1",   -- U +      "UXXXXXXX1",   -- X +      "UX00XX001",   -- 0 +      "UX10XX101",   -- 1 +      "UXXXXXXX1",   -- Z +      "UXXXXXXX1",   -- W +      "UX00XX001",   -- L +      "UX10XX101",   -- H +      "111111111"    -- - +     ); +  end Synth.Ieee.Std_Logic_1164; diff --git a/src/synth/synth-vhdl_eval.adb b/src/synth/synth-vhdl_eval.adb index e3b998afd..ab50a5e6b 100644 --- a/src/synth/synth-vhdl_eval.adb +++ b/src/synth/synth-vhdl_eval.adb @@ -25,6 +25,7 @@ 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; @@ -108,6 +109,39 @@ package body Synth.Vhdl_Eval is        return Res;     end Eval_Vector_Dyadic; +   function Eval_Logic_Vector_Scalar (Vect, Scal : Memtyp; +                                      Op : Table_2d; +                                      Neg : Boolean := False) 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); +         if Neg then +            Vr := Not_Table (Vr); +         end if; +         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_TF_Vector_Dyadic (Left, Right : Memtyp;                                     Op : Tf_Table_2d;                                     Loc : Syn_Src) return Memtyp @@ -325,12 +359,6 @@ package body Synth.Vhdl_Eval is        return Res;     end Execute_Shift_Operator; -   function Get_Static_Ulogic (Op : Memtyp) return Std_Ulogic is -   begin -      pragma Assert (Op.Typ.Kind = Type_Logic); -      return Std_Ulogic'Val (Read_U8 (Op.Mem)); -   end Get_Static_Ulogic; -     procedure Check_Integer_Overflow       (Val : in out Int64; Typ : Type_Acc; Loc : Syn_Src) is     begin @@ -712,23 +740,54 @@ package body Synth.Vhdl_Eval is             | 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_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_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_Dyadic (Left, Right, Match_Eq_Table, Expr); + +         when Iir_Predefined_Ieee_1164_And_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, And_Table); +         when Iir_Predefined_Ieee_1164_Or_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, Or_Table); +         when Iir_Predefined_Ieee_1164_Xor_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, Xor_Table); +         when Iir_Predefined_Ieee_1164_Nand_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, And_Table, True); +         when Iir_Predefined_Ieee_1164_Nor_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, Or_Table, True); +         when Iir_Predefined_Ieee_1164_Xnor_Suv_Log => +            return Eval_Logic_Vector_Scalar (Left, Right, Xor_Table, True); + +         when Iir_Predefined_Ieee_1164_And_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, And_Table); +         when Iir_Predefined_Ieee_1164_Or_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, Or_Table); +         when Iir_Predefined_Ieee_1164_Xor_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, Xor_Table); +         when Iir_Predefined_Ieee_1164_Nand_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, And_Table, True); +         when Iir_Predefined_Ieee_1164_Nor_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, Or_Table, True); +         when Iir_Predefined_Ieee_1164_Xnor_Log_Suv => +            return Eval_Logic_Vector_Scalar (Right, Left, Xor_Table, True);           when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Uns =>              declare @@ -1480,11 +1539,93 @@ package body Synth.Vhdl_Eval is                   (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_Enum_To_String => -            return Eval_Enum_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); | 
