diff options
| author | Tristan Gingold <tgingold@free.fr> | 2019-11-16 13:37:38 +0100 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2019-11-16 13:37:38 +0100 | 
| commit | f77e7c4e9dff80f8c478851b826e45f13a13cfe0 (patch) | |
| tree | c85451678862e76ec67e24cc0f9690cfbb89523f | |
| parent | f1046168bd29e08372159d99768ce9e8a014f61a (diff) | |
| download | ghdl-f77e7c4e9dff80f8c478851b826e45f13a13cfe0.tar.gz ghdl-f77e7c4e9dff80f8c478851b826e45f13a13cfe0.tar.bz2 ghdl-f77e7c4e9dff80f8c478851b826e45f13a13cfe0.zip  | |
synth: handle static mul sgn sgn.
| -rw-r--r-- | src/synth/synth-ieee-numeric_std.adb | 55 | ||||
| -rw-r--r-- | src/synth/synth-ieee-numeric_std.ads | 2 | ||||
| -rw-r--r-- | src/synth/synth-ieee-std_logic_1164.ads | 7 | ||||
| -rw-r--r-- | src/synth/synth-static_oper.adb | 19 | 
4 files changed, 82 insertions, 1 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb index 096e7fd9f..738146014 100644 --- a/src/synth/synth-ieee-numeric_std.adb +++ b/src/synth/synth-ieee-numeric_std.adb @@ -183,4 +183,59 @@ package body Synth.Ieee.Numeric_Std is        return Res;     end Mul_Uns_Uns; +   function Mul_Sgn_Sgn (L, R : Std_Logic_Vector) return Std_Logic_Vector +   is +      pragma Assert (L'First = 1); +      pragma Assert (R'First = 1); +      Res : Std_Logic_Vector (1 .. L'Last + R'Last); +      Lb, Rb, Vb, Carry : Sl_X01; +   begin +      if L'Last < 1 or R'Last < 1 then +         return Null_Vec; +      end if; +      Res := (others => '0'); +      --  Shift and add L, do not consider (yet) the sign bit of R. +      for I in 0 .. R'Last - 2 loop +         Rb := Sl_To_X01 (R (R'Last - I)); +         if Rb = '1' then +            --  Compute res := res + shift_left (l, i). +            Carry := '0'; +            for J in 0 .. L'Last - 1 loop +               Lb := L (L'Last - J); +               Vb := Res (Res'Last - (I + J)); +               Res (Res'Last - (I + J)) := Compute_Sum (Carry, Vb, Lb); +               Carry := Compute_Carry (Carry, Vb, Lb); +            end loop; +            --  Sign extend and propagate carry. +            Lb := R (1); +            for J in I + L'Last .. Res'Last - 1 loop +               Vb := Res (Res'Last - J); +               Res (Res'Last - J) := Compute_Sum (Carry, Vb, Lb); +               Carry := Compute_Carry (Carry, Vb, Lb); +            end loop; +         elsif Rb = 'X' then +            null; +            -- assert NO_WARNING +            --  report "NUMERIC_STD.""*"": non logical value detected" +            --  severity warning; +         end if; +      end loop; +      if R (1) = '1' then +         --  R is a negative number.  It is considered as: +         --   -2**n + (Rn-1 Rn-2 ... R0). +         --  Compute res := res - 2**n * l. +         Carry := '1'; +         for I in 0 .. L'Last - 1 loop +            Vb := Res (Res'Last - (R'Last - 1 + I)); +            Lb := Not_Table (L (L'Last - I)); +            Res (Res'Last - (R'Last - 1 + I)) := Compute_Sum (Carry, Vb, Lb); +            Carry := Compute_Carry (Carry, Vb, Lb); +         end loop; +         Vb := Res (1); +         Lb := Not_Table (L (1)); +         Res (1) := Compute_Sum (Carry, Vb, Lb); +      end if; +      return Res; +   end Mul_Sgn_Sgn; +  end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads index 3d9b8be0b..79ffd6a2f 100644 --- a/src/synth/synth-ieee-numeric_std.ads +++ b/src/synth/synth-ieee-numeric_std.ads @@ -33,4 +33,6 @@ package Synth.Ieee.Numeric_Std is                          return Std_Logic_Vector;     function Mul_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector; + +   function Mul_Sgn_Sgn (L, R : Std_Logic_Vector) return Std_Logic_Vector;  end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads index 242a417fb..433825e86 100644 --- a/src/synth/synth-ieee-std_logic_1164.ads +++ b/src/synth/synth-ieee-std_logic_1164.ads @@ -38,7 +38,7 @@ package Synth.Ieee.Std_Logic_1164 is     --  Vector of logic state.     type Std_Logic_Vector is array (Natural range <>) of Std_Ulogic; -   -- type Table_1d is array (Std_Ulogic) of Std_Ulogic; +   type Table_1d is array (Std_Ulogic) of Std_Ulogic;     type Table_2d is array (Std_Ulogic, Std_Ulogic) of Std_Ulogic;     And_Table : constant Table_2d := @@ -79,4 +79,9 @@ package Synth.Ieee.Std_Logic_1164 is        "UX10XX10X",   -- H        "UXXXXXXXX"    -- -       ); + +   Not_Table : constant Table_1d := +   --  UX01ZWLH- +      "UX10XX10X"; +  end Synth.Ieee.Std_Logic_1164; diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index 76c653329..668b7b431 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -154,6 +154,22 @@ package body Synth.Static_Oper is        end;     end Synth_Mul_Uns_Uns; +   function Synth_Mul_Sgn_Sgn (L, R : Value_Acc; Loc : Syn_Src) +                              return Value_Acc +   is +      pragma Unreferenced (Loc); +      L_Arr : Std_Logic_Vector (1 .. Natural (L.Arr.Len)); +      R_Arr : Std_Logic_Vector (1 .. Natural (R.Arr.Len)); +   begin +      To_Std_Logic_Vector (L, L_Arr); +      To_Std_Logic_Vector (R, R_Arr); +      declare +         Res_Arr : constant Std_Logic_Vector := Mul_Sgn_Sgn (L_Arr, R_Arr); +      begin +         return To_Value_Acc (Res_Arr, L.Typ.Vec_El); +      end; +   end Synth_Mul_Sgn_Sgn; +     function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc;                                              Imp : Node;                                              Left : Value_Acc; @@ -261,6 +277,9 @@ package body Synth.Static_Oper is           when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns =>              return Synth_Mul_Uns_Uns (Left, Right, Expr); +         when Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn => +            return Synth_Mul_Sgn_Sgn (Left, Right, Expr); +           when others =>              Error_Msg_Synth                (+Expr, "synth_static_dyadic_predefined: unhandled "  | 
